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