1/* Copyright (c) 2012-2016, The Linux Foundation. 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
32// System dependencies
33#include <stdlib.h>
34#include <utils/Errors.h>
35
36// Camera dependencies
37#include "camera.h"
38#include "camera3.h"
39#include "HAL/QCamera2HWI.h"
40#include "HAL3/QCamera3HWI.h"
41#include "util/QCameraFlash.h"
42#include "QCamera2Factory.h"
43#include "QCameraMuxer.h"
44
45extern "C" {
46#include "mm_camera_dbg.h"
47}
48
49using namespace android;
50
51namespace qcamera {
52
53QCamera2Factory *gQCamera2Factory = NULL;
54QCameraMuxer *gQCameraMuxer = NULL;
55pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
56//Total number of cameras opened simultaneously.
57//This variable updation is protected by gCamLock.
58uint8_t gNumCameraSessions = 0;
59
60volatile uint32_t gKpiDebugLevel = 1;
61
62/*===========================================================================
63 * FUNCTION   : QCamera2Factory
64 *
65 * DESCRIPTION: default constructor of QCamera2Factory
66 *
67 * PARAMETERS : none
68 *
69 * RETURN     : None
70 *==========================================================================*/
71QCamera2Factory::QCamera2Factory()
72{
73    camera_info info;
74    mHalDescriptors = NULL;
75    mCallbacks = NULL;
76    mNumOfCameras = get_num_of_cameras();
77    int bDualCamera = 0;
78    char propDefault[PROPERTY_VALUE_MAX];
79    char prop[PROPERTY_VALUE_MAX];
80    property_get("persist.camera.HAL3.enabled", prop, "1");
81    int isHAL3Enabled = atoi(prop);
82
83    // Signifies whether system has to enable dual camera mode
84    snprintf(propDefault, PROPERTY_VALUE_MAX, "%d", isDualCamAvailable(isHAL3Enabled));
85    property_get("persist.camera.dual.camera", prop, propDefault);
86    bDualCamera = atoi(prop);
87    LOGH("dualCamera:%d ", bDualCamera);
88
89    if(bDualCamera) {
90        LOGI("Enabling QCamera Muxer");
91        if (!gQCameraMuxer) {
92            QCameraMuxer::getCameraMuxer(&gQCameraMuxer, mNumOfCameras);
93            if (!gQCameraMuxer) {
94                LOGE("Error !! Failed to get QCameraMuxer");
95            }
96        }
97    }
98    if (!gQCameraMuxer && (mNumOfCameras > 0) &&
99            (mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
100        mHalDescriptors = new hal_desc[mNumOfCameras];
101        if ( NULL != mHalDescriptors) {
102            uint32_t cameraId = 0;
103
104            for (int i = 0; i < mNumOfCameras ; i++, cameraId++) {
105                mHalDescriptors[i].cameraId = cameraId;
106                // Set Device version to 3.x when both HAL3 is enabled & its BAYER sensor
107                if (isHAL3Enabled && !(is_yuv_sensor(cameraId))) {
108                    mHalDescriptors[i].device_version =
109                            CAMERA_DEVICE_API_VERSION_3_0;
110                } else {
111                    mHalDescriptors[i].device_version =
112                            CAMERA_DEVICE_API_VERSION_1_0;
113                }
114                //Query camera at this point in order
115                //to avoid any delays during subsequent
116                //calls to 'getCameraInfo()'
117                getCameraInfo(i, &info);
118            }
119        } else {
120            LOGE("Not enough resources to allocate HAL descriptor table!");
121        }
122    } else {
123        LOGI("%d camera devices detected!", mNumOfCameras);
124    }
125}
126
127/*===========================================================================
128 * FUNCTION   : ~QCamera2Factory
129 *
130 * DESCRIPTION: deconstructor of QCamera2Factory
131 *
132 * PARAMETERS : none
133 *
134 * RETURN     : None
135 *==========================================================================*/
136QCamera2Factory::~QCamera2Factory()
137{
138    if ( NULL != mHalDescriptors ) {
139        delete [] mHalDescriptors;
140    }
141    if (gQCameraMuxer) {
142        delete gQCameraMuxer;
143        gQCameraMuxer = NULL;
144    }
145}
146
147/*===========================================================================
148 * FUNCTION   : get_number_of_cameras
149 *
150 * DESCRIPTION: static function to query number of cameras detected
151 *
152 * PARAMETERS : none
153 *
154 * RETURN     : number of cameras detected
155 *==========================================================================*/
156int QCamera2Factory::get_number_of_cameras()
157{
158    int numCameras = 0;
159
160    if (!gQCamera2Factory) {
161        gQCamera2Factory = new QCamera2Factory();
162        if (!gQCamera2Factory) {
163            LOGE("Failed to allocate Camera2Factory object");
164            return 0;
165        }
166    }
167
168    if(gQCameraMuxer)
169        numCameras = gQCameraMuxer->get_number_of_cameras();
170    else
171        numCameras = gQCamera2Factory->getNumberOfCameras();
172
173    LOGH("num of cameras: %d", numCameras);
174    return numCameras;
175}
176
177/*===========================================================================
178 * FUNCTION   : get_camera_info
179 *
180 * DESCRIPTION: static function to query camera information with its ID
181 *
182 * PARAMETERS :
183 *   @camera_id : camera ID
184 *   @info      : ptr to camera info struct
185 *
186 * RETURN     : int32_t type of status
187 *              NO_ERROR  -- success
188 *              none-zero failure code
189 *==========================================================================*/
190int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
191{
192    int rc = NO_ERROR;
193
194    if(gQCameraMuxer)
195        rc = gQCameraMuxer->get_camera_info(camera_id, info);
196    else
197        rc =  gQCamera2Factory->getCameraInfo(camera_id, info);
198
199    return rc;
200}
201
202/*===========================================================================
203 * FUNCTION   : set_callbacks
204 *
205 * DESCRIPTION: static function to set callbacks function to camera module
206 *
207 * PARAMETERS :
208 *   @callbacks : ptr to callback functions
209 *
210 * RETURN     : NO_ERROR  -- success
211 *              none-zero failure code
212 *==========================================================================*/
213int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
214{
215    int rc = NO_ERROR;
216    if(gQCameraMuxer)
217        rc = gQCameraMuxer->set_callbacks(callbacks);
218    else
219        rc =  gQCamera2Factory->setCallbacks(callbacks);
220
221    return rc;
222}
223
224/*===========================================================================
225 * FUNCTION   : open_legacy
226 *
227 * DESCRIPTION: Function to open older hal version implementation
228 *
229 * PARAMETERS :
230 *   @hw_device : ptr to struct storing camera hardware device info
231 *   @camera_id : camera ID
232 *   @halVersion: Based on camera_module_t.common.module_api_version
233 *
234 * RETURN     : 0  -- success
235 *              none-zero failure code
236 *==========================================================================*/
237int QCamera2Factory::open_legacy(const struct hw_module_t* module,
238            const char* id, uint32_t halVersion, struct hw_device_t** device)
239{
240    int rc = NO_ERROR;
241    if (module != &HAL_MODULE_INFO_SYM.common) {
242        LOGE("Invalid module. Trying to open %p, expect %p",
243            module, &HAL_MODULE_INFO_SYM.common);
244        return INVALID_OPERATION;
245    }
246    if (!id) {
247        LOGE("Invalid camera id");
248        return BAD_VALUE;
249    }
250    if(gQCameraMuxer)
251        rc =  gQCameraMuxer->open_legacy(module, id, halVersion, device);
252    else
253        rc =  gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
254
255    return rc;
256}
257
258/*===========================================================================
259 * FUNCTION   : set_torch_mode
260 *
261 * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
262 *
263 * PARAMETERS :
264 *   @camera_id : camera ID
265 *   @on        : Indicates whether to turn the flash on or off
266 *
267 * RETURN     : 0  -- success
268 *              none-zero failure code
269 *==========================================================================*/
270int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
271{
272    return gQCamera2Factory->setTorchMode(camera_id, on);
273}
274
275/*===========================================================================
276 * FUNCTION   : getNumberOfCameras
277 *
278 * DESCRIPTION: query number of cameras detected
279 *
280 * PARAMETERS : none
281 *
282 * RETURN     : number of cameras detected
283 *==========================================================================*/
284int QCamera2Factory::getNumberOfCameras()
285{
286    return mNumOfCameras;
287}
288
289/*===========================================================================
290 * FUNCTION   : getCameraInfo
291 *
292 * DESCRIPTION: query camera information with its ID
293 *
294 * PARAMETERS :
295 *   @camera_id : camera ID
296 *   @info      : ptr to camera info struct
297 *
298 * RETURN     : int32_t type of status
299 *              NO_ERROR  -- success
300 *              none-zero failure code
301 *==========================================================================*/
302int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
303{
304    int rc;
305    cam_sync_type_t cam_type = CAM_TYPE_MAIN;
306
307    if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
308        (camera_id < 0)) {
309        LOGE("Error getting camera info!! mNumOfCameras = %d,"
310                "camera_id = %d, info = %p",
311                 mNumOfCameras, camera_id, info);
312        return -ENODEV;
313    }
314
315    if ( NULL == mHalDescriptors ) {
316        LOGE("Hal descriptor table is not initialized!");
317        return NO_INIT;
318    }
319
320    if ( mHalDescriptors[camera_id].device_version ==
321            CAMERA_DEVICE_API_VERSION_3_0 ) {
322        rc = QCamera3HardwareInterface::getCamInfo(
323                mHalDescriptors[camera_id].cameraId, info);
324    } else if (mHalDescriptors[camera_id].device_version ==
325            CAMERA_DEVICE_API_VERSION_1_0) {
326        rc = QCamera2HardwareInterface::getCapabilities(
327                mHalDescriptors[camera_id].cameraId, info, &cam_type);
328    } else {
329        LOGE("Device version for camera id %d invalid %d",
330              camera_id,
331              mHalDescriptors[camera_id].device_version);
332        return BAD_VALUE;
333    }
334
335    return rc;
336}
337
338/*===========================================================================
339 * FUNCTION   : setCallbacks
340 *
341 * DESCRIPTION: set callback functions to send asynchronous notifications to
342 *              frameworks.
343 *
344 * PARAMETERS :
345 *   @callbacks : callback function pointer
346 *
347 * RETURN     :
348 *              NO_ERROR  -- success
349 *              none-zero failure code
350 *==========================================================================*/
351int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
352{
353    int rc = NO_ERROR;
354    mCallbacks = callbacks;
355
356    rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
357    if (rc != 0) {
358        LOGE("Failed to register callbacks with flash module!");
359    }
360
361    return rc;
362}
363
364/*===========================================================================
365 * FUNCTION   : cameraDeviceOpen
366 *
367 * DESCRIPTION: open a camera device with its ID
368 *
369 * PARAMETERS :
370 *   @camera_id : camera ID
371 *   @hw_device : ptr to struct storing camera hardware device info
372 *
373 * RETURN     : int32_t type of status
374 *              NO_ERROR  -- success
375 *              none-zero failure code
376 *==========================================================================*/
377int QCamera2Factory::cameraDeviceOpen(int camera_id,
378                    struct hw_device_t **hw_device)
379{
380    int rc = NO_ERROR;
381    if (camera_id < 0 || camera_id >= mNumOfCameras)
382        return -ENODEV;
383
384    if ( NULL == mHalDescriptors ) {
385        LOGE("Hal descriptor table is not initialized!");
386        return NO_INIT;
387    }
388
389    LOGI("Open camera id %d API version %d",
390            camera_id, mHalDescriptors[camera_id].device_version);
391
392    if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
393        QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
394                mCallbacks);
395        if (!hw) {
396            LOGE("Allocation of hardware interface failed");
397            return NO_MEMORY;
398        }
399        rc = hw->openCamera(hw_device);
400        if (rc != 0) {
401            delete hw;
402        }
403    } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
404        QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
405        if (!hw) {
406            LOGE("Allocation of hardware interface failed");
407            return NO_MEMORY;
408        }
409        rc = hw->openCamera(hw_device);
410        if (rc != NO_ERROR) {
411            delete hw;
412        }
413    } else {
414        LOGE("Device version for camera id %d invalid %d",
415              camera_id,
416              mHalDescriptors[camera_id].device_version);
417        return BAD_VALUE;
418    }
419
420    return rc;
421}
422
423/*===========================================================================
424 * FUNCTION   : camera_device_open
425 *
426 * DESCRIPTION: static function to open a camera device by its ID
427 *
428 * PARAMETERS :
429 *   @camera_id : camera ID
430 *   @hw_device : ptr to struct storing camera hardware device info
431 *
432 * RETURN     : int32_t type of status
433 *              NO_ERROR  -- success
434 *              none-zero failure code
435 *==========================================================================*/
436int QCamera2Factory::camera_device_open(
437    const struct hw_module_t *module, const char *id,
438    struct hw_device_t **hw_device)
439{
440    int rc = NO_ERROR;
441    if (module != &HAL_MODULE_INFO_SYM.common) {
442        LOGE("Invalid module. Trying to open %p, expect %p",
443            module, &HAL_MODULE_INFO_SYM.common);
444        return INVALID_OPERATION;
445    }
446    if (!id) {
447        LOGE("Invalid camera id");
448        return BAD_VALUE;
449    }
450
451    if(gQCameraMuxer)
452        rc =  gQCameraMuxer->camera_device_open(module, id, hw_device);
453    else
454        rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
455
456    return rc;
457}
458
459struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
460    .open = QCamera2Factory::camera_device_open,
461};
462
463/*===========================================================================
464 * FUNCTION   : openLegacy
465 *
466 * DESCRIPTION: Function to open older hal version implementation
467 *
468 * PARAMETERS :
469 *   @camera_id : camera ID
470 *   @halVersion: Based on camera_module_t.common.module_api_version
471 *   @hw_device : ptr to struct storing camera hardware device info
472 *
473 * RETURN     : 0  -- success
474 *              none-zero failure code
475 *==========================================================================*/
476int QCamera2Factory::openLegacy(
477        int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
478{
479    int rc = NO_ERROR;
480
481    LOGI("openLegacy halVersion: %d", halVersion);
482    //Assumption: all cameras can support legacy API version
483    if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
484        return -ENODEV;
485
486    switch(halVersion)
487    {
488        case CAMERA_DEVICE_API_VERSION_1_0:
489        {
490            QCamera2HardwareInterface *hw =
491                new QCamera2HardwareInterface((uint32_t)cameraId);
492            if (!hw) {
493                LOGE("Allocation of hardware interface failed");
494                return NO_MEMORY;
495            }
496            rc = hw->openCamera(hw_device);
497            if (rc != NO_ERROR) {
498                delete hw;
499            }
500            break;
501        }
502        default:
503            LOGE("Device API version: %d for camera id %d invalid",
504                 halVersion, cameraId);
505            return BAD_VALUE;
506    }
507
508    return rc;
509}
510
511/*===========================================================================
512 * FUNCTION   : setTorchMode
513 *
514 * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
515 *
516 * PARAMETERS :
517 *   @camera_id : camera ID
518 *   @on        : Indicates whether to turn the flash on or off
519 *
520 * RETURN     : 0  -- success
521 *              none-zero failure code
522 *==========================================================================*/
523int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
524{
525    int retVal(0);
526    long cameraIdLong(-1);
527    int cameraIdInt(-1);
528    char* endPointer = NULL;
529    errno = 0;
530    QCameraFlash& flash = QCameraFlash::getInstance();
531
532    cameraIdLong = strtol(camera_id, &endPointer, 10);
533
534    if ((errno == ERANGE) ||
535            (cameraIdLong < 0) ||
536            (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
537            (endPointer == camera_id) ||
538            (*endPointer != '\0')) {
539        retVal = -EINVAL;
540    } else if (on) {
541        cameraIdInt = static_cast<int>(cameraIdLong);
542        retVal = flash.initFlash(cameraIdInt);
543
544        if (retVal == 0) {
545            retVal = flash.setFlashMode(cameraIdInt, on);
546            if ((retVal == 0) && (mCallbacks != NULL)) {
547                mCallbacks->torch_mode_status_change(mCallbacks,
548                        camera_id,
549                        TORCH_MODE_STATUS_AVAILABLE_ON);
550            } else if (retVal == -EALREADY) {
551                // Flash is already on, so treat this as a success.
552                retVal = 0;
553            }
554        }
555    } else {
556        cameraIdInt = static_cast<int>(cameraIdLong);
557        retVal = flash.setFlashMode(cameraIdInt, on);
558
559        if (retVal == 0) {
560            retVal = flash.deinitFlash(cameraIdInt);
561            if ((retVal == 0) && (mCallbacks != NULL)) {
562                mCallbacks->torch_mode_status_change(mCallbacks,
563                        camera_id,
564                        TORCH_MODE_STATUS_AVAILABLE_OFF);
565            }
566        } else if (retVal == -EALREADY) {
567            // Flash is already off, so treat this as a success.
568            retVal = 0;
569        }
570    }
571
572    return retVal;
573}
574
575/*===========================================================================
576 * FUNCTION   : isDualCamAvailable
577 *
578 * DESCRIPTION: Function to check whether we have dual Camera HW available
579 *
580 * PARAMETERS :
581 *   @hal3Enabled : HAL3 enable flag
582 *
583 * RETURN     : bool - true : have Dual Camera HW available
584 *                           false : not have Dual Camera HW available
585 *==========================================================================*/
586bool QCamera2Factory::isDualCamAvailable(int hal3Enabled)
587{
588    bool rc = FALSE;
589    int i = 0;
590    camera_info info;
591    cam_sync_type_t cam_type = CAM_TYPE_MAIN;
592
593    for (i = 0; i < mNumOfCameras; i++) {
594        if (!hal3Enabled) {
595            QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
596        }
597
598        if(cam_type == CAM_TYPE_AUX) {
599            LOGH("Have Dual Camera HW Avaiable.");
600            rc = TRUE;
601            break;
602        }
603    }
604
605    return rc;
606}
607
608}; // namespace qcamera
609
610