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     int i = 0;
     63     mHalDescriptors = NULL;
     64     mCallbacks = NULL;
     65     mNumOfCameras = get_num_of_cameras();
     66     char prop[PROPERTY_VALUE_MAX];
     67     property_get("persist.camera.HAL3.enabled", prop, "0");
     68     int isHAL3Enabled = atoi(prop);
     69 
     70     if ((mNumOfCameras > 0) && (mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
     71         mHalDescriptors = new hal_desc[mNumOfCameras];
     72         if ( NULL != mHalDescriptors) {
     73             uint32_t cameraId = 0;
     74 
     75             for (; i < mNumOfCameras ; i++, cameraId++) {
     76                 mHalDescriptors[i].cameraId = cameraId;
     77                 if (isHAL3Enabled) {
     78                     mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_3_0;
     79                 } else {
     80                     mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_1_0;
     81                 }
     82                 //Query camera at this point in order
     83                 //to avoid any delays during subsequent
     84                 //calls to 'getCameraInfo()'
     85                 getCameraInfo(i, &info);
     86             }
     87         } else {
     88             ALOGE("%s: Not enough resources to allocate HAL descriptor table!",
     89                   __func__);
     90         }
     91     } else {
     92         ALOGE("%s: %d camera devices detected!", __func__, mNumOfCameras);
     93     }
     94 }
     95 
     96 /*===========================================================================
     97  * FUNCTION   : ~QCamera2Factory
     98  *
     99  * DESCRIPTION: deconstructor of QCamera2Factory
    100  *
    101  * PARAMETERS : none
    102  *
    103  * RETURN     : None
    104  *==========================================================================*/
    105 QCamera2Factory::~QCamera2Factory()
    106 {
    107     if ( NULL != mHalDescriptors ) {
    108         delete [] mHalDescriptors;
    109     }
    110 }
    111 
    112 /*===========================================================================
    113  * FUNCTION   : get_number_of_cameras
    114  *
    115  * DESCRIPTION: static function to query number of cameras detected
    116  *
    117  * PARAMETERS : none
    118  *
    119  * RETURN     : number of cameras detected
    120  *==========================================================================*/
    121 int QCamera2Factory::get_number_of_cameras()
    122 {
    123     if (!gQCamera2Factory) {
    124         gQCamera2Factory = new QCamera2Factory();
    125         if (!gQCamera2Factory) {
    126             ALOGE("%s: Failed to allocate Camera2Factory object", __func__);
    127             return 0;
    128         }
    129     }
    130     return gQCamera2Factory->getNumberOfCameras();
    131 }
    132 
    133 /*===========================================================================
    134  * FUNCTION   : get_camera_info
    135  *
    136  * DESCRIPTION: static function to query camera information with its ID
    137  *
    138  * PARAMETERS :
    139  *   @camera_id : camera ID
    140  *   @info      : ptr to camera info struct
    141  *
    142  * RETURN     : int32_t type of status
    143  *              NO_ERROR  -- success
    144  *              none-zero failure code
    145  *==========================================================================*/
    146 int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
    147 {
    148     return gQCamera2Factory->getCameraInfo(camera_id, info);
    149 }
    150 
    151 /*===========================================================================
    152  * FUNCTION   : set_callbacks
    153  *
    154  * DESCRIPTION: static function to set callbacks function to camera module
    155  *
    156  * PARAMETERS :
    157  *   @callbacks : ptr to callback functions
    158  *
    159  * RETURN     : NO_ERROR  -- success
    160  *              none-zero failure code
    161  *==========================================================================*/
    162 int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
    163 {
    164     return gQCamera2Factory->setCallbacks(callbacks);
    165 }
    166 
    167 /*===========================================================================
    168  * FUNCTION   : open_legacy
    169  *
    170  * DESCRIPTION: Function to open older hal version implementation
    171  *
    172  * PARAMETERS :
    173  *   @hw_device : ptr to struct storing camera hardware device info
    174  *   @camera_id : camera ID
    175  *   @halVersion: Based on camera_module_t.common.module_api_version
    176  *
    177  * RETURN     : 0  -- success
    178  *              none-zero failure code
    179  *==========================================================================*/
    180 int QCamera2Factory::open_legacy(const struct hw_module_t* module,
    181             const char* id, uint32_t halVersion, struct hw_device_t** device)
    182 {
    183     return -ENOSYS;
    184 }
    185 
    186 /*===========================================================================
    187  * FUNCTION   : set_torch_mode
    188  *
    189  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
    190  *
    191  * PARAMETERS :
    192  *   @camera_id : camera ID
    193  *   @on        : Indicates whether to turn the flash on or off
    194  *
    195  * RETURN     : 0  -- success
    196  *              none-zero failure code
    197  *==========================================================================*/
    198 int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
    199 {
    200     return gQCamera2Factory->setTorchMode(camera_id, on);
    201 }
    202 
    203 /*===========================================================================
    204  * FUNCTION   : getNumberOfCameras
    205  *
    206  * DESCRIPTION: query number of cameras detected
    207  *
    208  * PARAMETERS : none
    209  *
    210  * RETURN     : number of cameras detected
    211  *==========================================================================*/
    212 int QCamera2Factory::getNumberOfCameras()
    213 {
    214     return mNumOfCameras;
    215 }
    216 
    217 /*===========================================================================
    218  * FUNCTION   : getCameraInfo
    219  *
    220  * DESCRIPTION: query camera information with its ID
    221  *
    222  * PARAMETERS :
    223  *   @camera_id : camera ID
    224  *   @info      : ptr to camera info struct
    225  *
    226  * RETURN     : int32_t type of status
    227  *              NO_ERROR  -- success
    228  *              none-zero failure code
    229  *==========================================================================*/
    230 int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
    231 {
    232     int rc;
    233     ALOGV("%s: E, camera_id = %d", __func__, camera_id);
    234 
    235     if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
    236         (camera_id < 0)) {
    237         return -ENODEV;
    238     }
    239 
    240     if ( NULL == mHalDescriptors ) {
    241         ALOGE("%s : Hal descriptor table is not initialized!", __func__);
    242         return NO_INIT;
    243     }
    244 
    245     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
    246         rc = QCamera3HardwareInterface::getCamInfo(mHalDescriptors[camera_id].cameraId, info);
    247     } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
    248         rc = QCamera2HardwareInterface::getCapabilities(mHalDescriptors[camera_id].cameraId, info);
    249     } else {
    250         ALOGE("%s: Device version for camera id %d invalid %d",
    251               __func__,
    252               camera_id,
    253               mHalDescriptors[camera_id].device_version);
    254         return BAD_VALUE;
    255     }
    256 
    257     ALOGV("%s: X", __func__);
    258     return rc;
    259 }
    260 
    261 /*===========================================================================
    262  * FUNCTION   : setCallbacks
    263  *
    264  * DESCRIPTION: set callback functions to send asynchronous notifications to
    265  *              frameworks.
    266  *
    267  * PARAMETERS :
    268  *   @callbacks : callback function pointer
    269  *
    270  * RETURN     :
    271  *              NO_ERROR  -- success
    272  *              none-zero failure code
    273  *==========================================================================*/
    274 int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
    275 {
    276     int rc = NO_ERROR;
    277     mCallbacks = callbacks;
    278 
    279     rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
    280     if (rc != 0) {
    281         ALOGE("%s : Failed to register callbacks with flash module!", __func__);
    282     }
    283 
    284     return rc;
    285 }
    286 
    287 /*===========================================================================
    288  * FUNCTION   : cameraDeviceOpen
    289  *
    290  * DESCRIPTION: open a camera device with its ID
    291  *
    292  * PARAMETERS :
    293  *   @camera_id : camera ID
    294  *   @hw_device : ptr to struct storing camera hardware device info
    295  *
    296  * RETURN     : int32_t type of status
    297  *              NO_ERROR  -- success
    298  *              none-zero failure code
    299  *==========================================================================*/
    300 int QCamera2Factory::cameraDeviceOpen(int camera_id,
    301                     struct hw_device_t **hw_device)
    302 {
    303     int rc = NO_ERROR;
    304     if (camera_id < 0 || camera_id >= mNumOfCameras)
    305         return -ENODEV;
    306 
    307     if ( NULL == mHalDescriptors ) {
    308         ALOGE("%s : Hal descriptor table is not initialized!", __func__);
    309         return NO_INIT;
    310     }
    311 
    312     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
    313         QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
    314                 mCallbacks);
    315         if (!hw) {
    316             ALOGE("Allocation of hardware interface failed");
    317             return NO_MEMORY;
    318         }
    319         rc = hw->openCamera(hw_device);
    320         if (rc != 0) {
    321             delete hw;
    322         }
    323     } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
    324         QCamera2HardwareInterface *hw = new QCamera2HardwareInterface(camera_id);
    325         if (!hw) {
    326             ALOGE("Allocation of hardware interface failed");
    327             return NO_MEMORY;
    328         }
    329         rc = hw->openCamera(hw_device);
    330         if (rc != NO_ERROR) {
    331             delete hw;
    332         }
    333     } else {
    334         ALOGE("%s: Device version for camera id %d invalid %d",
    335               __func__,
    336               camera_id,
    337               mHalDescriptors[camera_id].device_version);
    338         return BAD_VALUE;
    339     }
    340 
    341     return rc;
    342 }
    343 
    344 /*===========================================================================
    345  * FUNCTION   : camera_device_open
    346  *
    347  * DESCRIPTION: static function to open a camera device by its ID
    348  *
    349  * PARAMETERS :
    350  *   @camera_id : camera ID
    351  *   @hw_device : ptr to struct storing camera hardware device info
    352  *
    353  * RETURN     : int32_t type of status
    354  *              NO_ERROR  -- success
    355  *              none-zero failure code
    356  *==========================================================================*/
    357 int QCamera2Factory::camera_device_open(
    358     const struct hw_module_t *module, const char *id,
    359     struct hw_device_t **hw_device)
    360 {
    361     if (module != &HAL_MODULE_INFO_SYM.common) {
    362         ALOGE("Invalid module. Trying to open %p, expect %p",
    363             module, &HAL_MODULE_INFO_SYM.common);
    364         return INVALID_OPERATION;
    365     }
    366     if (!id) {
    367         ALOGE("Invalid camera id");
    368         return BAD_VALUE;
    369     }
    370     return gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
    371 }
    372 
    373 struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
    374     open: QCamera2Factory::camera_device_open,
    375 };
    376 
    377 /*===========================================================================
    378  * FUNCTION   : setTorchMode
    379  *
    380  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
    381  *
    382  * PARAMETERS :
    383  *   @camera_id : camera ID
    384  *   @on        : Indicates whether to turn the flash on or off
    385  *
    386  * RETURN     : 0  -- success
    387  *              none-zero failure code
    388  *==========================================================================*/
    389 int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
    390 {
    391     int retVal(0);
    392     long cameraIdLong(-1);
    393     int cameraIdInt(-1);
    394     char* endPointer = NULL;
    395     errno = 0;
    396     QCameraFlash& flash = QCameraFlash::getInstance();
    397 
    398     cameraIdLong = strtol(camera_id, &endPointer, 10);
    399 
    400     if ((errno == ERANGE) ||
    401             (cameraIdLong < 0) ||
    402             (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
    403             (endPointer == camera_id) ||
    404             (*endPointer != '\0')) {
    405         retVal = -EINVAL;
    406     } else if (on) {
    407         cameraIdInt = static_cast<int>(cameraIdLong);
    408         retVal = flash.initFlash(cameraIdInt);
    409 
    410         if (retVal == 0) {
    411             retVal = flash.setFlashMode(cameraIdInt, on);
    412             if ((retVal == 0) && (mCallbacks != NULL)) {
    413                 mCallbacks->torch_mode_status_change(mCallbacks,
    414                         camera_id,
    415                         TORCH_MODE_STATUS_AVAILABLE_ON);
    416             } else if (retVal == -EALREADY) {
    417                 // Flash is already on, so treat this as a success.
    418                 retVal = 0;
    419             }
    420         }
    421     } else {
    422         cameraIdInt = static_cast<int>(cameraIdLong);
    423         retVal = flash.setFlashMode(cameraIdInt, on);
    424 
    425         if (retVal == 0) {
    426             retVal = flash.deinitFlash(cameraIdInt);
    427             if ((retVal == 0) && (mCallbacks != NULL)) {
    428                 mCallbacks->torch_mode_status_change(mCallbacks,
    429                         camera_id,
    430                         TORCH_MODE_STATUS_AVAILABLE_OFF);
    431             }
    432         } else if (retVal == -EALREADY) {
    433             // Flash is already off, so treat this as a success.
    434             retVal = 0;
    435         }
    436     }
    437 
    438     return retVal;
    439 }
    440 
    441 }; // namespace qcamera
    442 
    443