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