• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   : set_callbacks
222  *
223  * DESCRIPTION: static function to set callbacks function to camera module
224  *
225  * PARAMETERS :
226  *   @callbacks : ptr to callback functions
227  *
228  * RETURN     : NO_ERROR  -- success
229  *              none-zero failure code
230  *==========================================================================*/
231 int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
232 {
233     int rc = NO_ERROR;
234 #ifdef QCAMERA_HAL1_SUPPORT
235     if(gQCameraMuxer)
236         rc = gQCameraMuxer->set_callbacks(callbacks);
237     else
238 #endif
239         rc =  gQCamera2Factory->setCallbacks(callbacks);
240 
241     return rc;
242 }
243 
244 /*===========================================================================
245  * FUNCTION   : open_legacy
246  *
247  * DESCRIPTION: Function to open older hal version implementation
248  *
249  * PARAMETERS :
250  *   @hw_device : ptr to struct storing camera hardware device info
251  *   @camera_id : camera ID
252  *   @halVersion: Based on camera_module_t.common.module_api_version
253  *
254  * RETURN     : 0  -- success
255  *              none-zero failure code
256  *==========================================================================*/
257 int QCamera2Factory::open_legacy(const struct hw_module_t* module,
258             const char* id, uint32_t halVersion, struct hw_device_t** device)
259 {
260     int rc = NO_ERROR;
261     if (module != &HAL_MODULE_INFO_SYM.common) {
262         LOGE("Invalid module. Trying to open %p, expect %p",
263             module, &HAL_MODULE_INFO_SYM.common);
264         return INVALID_OPERATION;
265     }
266     if (!id) {
267         LOGE("Invalid camera id");
268         return BAD_VALUE;
269     }
270 #ifdef QCAMERA_HAL1_SUPPORT
271     if(gQCameraMuxer)
272         rc =  gQCameraMuxer->open_legacy(module, id, halVersion, device);
273     else
274 #endif
275         rc =  gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
276 
277     return rc;
278 }
279 
280 /*===========================================================================
281  * FUNCTION   : set_torch_mode
282  *
283  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
284  *
285  * PARAMETERS :
286  *   @camera_id : camera ID
287  *   @on        : Indicates whether to turn the flash on or off
288  *
289  * RETURN     : 0  -- success
290  *              none-zero failure code
291  *==========================================================================*/
292 int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
293 {
294     return gQCamera2Factory->setTorchMode(camera_id, on);
295 }
296 
297 /*===========================================================================
298  * FUNCTION   : getNumberOfCameras
299  *
300  * DESCRIPTION: query number of cameras detected
301  *
302  * PARAMETERS : none
303  *
304  * RETURN     : number of cameras detected
305  *==========================================================================*/
306 int QCamera2Factory::getNumberOfCameras()
307 {
308     return mNumOfCameras_expose;
309 }
310 
311 /*===========================================================================
312  * FUNCTION   : getCameraInfo
313  *
314  * DESCRIPTION: query camera information with its ID
315  *
316  * PARAMETERS :
317  *   @camera_id : camera ID
318  *   @info      : ptr to camera info struct
319  *
320  * RETURN     : int32_t type of status
321  *              NO_ERROR  -- success
322  *              none-zero failure code
323  *==========================================================================*/
324 int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
325 {
326     int rc;
327 
328     if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
329         (camera_id < 0)) {
330         LOGE("Error getting camera info!! mNumOfCameras = %d,"
331                 "camera_id = %d, info = %p",
332                  mNumOfCameras, camera_id, info);
333         return -ENODEV;
334     }
335 
336     if ( NULL == mHalDescriptors ) {
337         LOGE("Hal descriptor table is not initialized!");
338         return NO_INIT;
339     }
340 
341     LOGI("Camera id %d API version %d",
342             camera_id, mHalDescriptors[camera_id].device_version);
343 
344     // Need ANDROID_FLASH_INFO_AVAILABLE property for flashlight widget to
345     // work and so get the static data regardless of HAL version
346     rc = QCamera3HardwareInterface::getCamInfo(
347             mHalDescriptors[camera_id].cameraId, info);
348     if (mHalDescriptors[camera_id].device_version ==
349             CAMERA_DEVICE_API_VERSION_1_0) {
350         info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
351     }
352     return rc;
353 }
354 
355 /*===========================================================================
356  * FUNCTION   : setCallbacks
357  *
358  * DESCRIPTION: set callback functions to send asynchronous notifications to
359  *              frameworks.
360  *
361  * PARAMETERS :
362  *   @callbacks : callback function pointer
363  *
364  * RETURN     :
365  *              NO_ERROR  -- success
366  *              none-zero failure code
367  *==========================================================================*/
368 int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
369 {
370     int rc = NO_ERROR;
371     mCallbacks = callbacks;
372 
373     rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
374     if (rc != 0) {
375         LOGE("Failed to register callbacks with flash module!");
376     }
377 
378     return rc;
379 }
380 
381 /*===========================================================================
382  * FUNCTION   : cameraDeviceOpen
383  *
384  * DESCRIPTION: open a camera device with its ID
385  *
386  * PARAMETERS :
387  *   @camera_id : camera ID
388  *   @hw_device : ptr to struct storing camera hardware device info
389  *
390  * RETURN     : int32_t type of status
391  *              NO_ERROR  -- success
392  *              none-zero failure code
393  *==========================================================================*/
394 int QCamera2Factory::cameraDeviceOpen(int camera_id,
395                     struct hw_device_t **hw_device)
396 {
397     int rc = NO_ERROR;
398     if (camera_id < 0 || camera_id >= mNumOfCameras)
399         return -ENODEV;
400 
401     if ( NULL == mHalDescriptors ) {
402         LOGE("Hal descriptor table is not initialized!");
403         return NO_INIT;
404     }
405 
406     LOGI("Open camera id %d API version %d",
407             camera_id, mHalDescriptors[camera_id].device_version);
408 
409     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
410         CAMSCOPE_INIT(CAMSCOPE_SECTION_HAL);
411         QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
412                 mCallbacks);
413         if (!hw) {
414             LOGE("Allocation of hardware interface failed");
415             return NO_MEMORY;
416         }
417         rc = hw->openCamera(hw_device);
418         if (rc != 0) {
419             delete hw;
420         }
421     }
422 #ifdef QCAMERA_HAL1_SUPPORT
423     else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
424         QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
425         if (!hw) {
426             LOGE("Allocation of hardware interface failed");
427             return NO_MEMORY;
428         }
429         rc = hw->openCamera(hw_device);
430         if (rc != NO_ERROR) {
431             delete hw;
432         }
433     }
434 #endif
435     else {
436         LOGE("Device version for camera id %d invalid %d",
437               camera_id,
438               mHalDescriptors[camera_id].device_version);
439         return BAD_VALUE;
440     }
441 
442     return rc;
443 }
444 
445 /*===========================================================================
446  * FUNCTION   : camera_device_open
447  *
448  * DESCRIPTION: static function to open a camera device by its ID
449  *
450  * PARAMETERS :
451  *   @camera_id : camera ID
452  *   @hw_device : ptr to struct storing camera hardware device info
453  *
454  * RETURN     : int32_t type of status
455  *              NO_ERROR  -- success
456  *              none-zero failure code
457  *==========================================================================*/
458 int QCamera2Factory::camera_device_open(
459     const struct hw_module_t *module, const char *id,
460     struct hw_device_t **hw_device)
461 {
462     int rc = NO_ERROR;
463     if (module != &HAL_MODULE_INFO_SYM.common) {
464         LOGE("Invalid module. Trying to open %p, expect %p",
465             module, &HAL_MODULE_INFO_SYM.common);
466         return INVALID_OPERATION;
467     }
468     if (!id) {
469         LOGE("Invalid camera id");
470         return BAD_VALUE;
471     }
472 #ifdef QCAMERA_HAL1_SUPPORT
473     if(gQCameraMuxer)
474         rc =  gQCameraMuxer->camera_device_open(module, id, hw_device);
475     else
476 #endif
477         rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
478     return rc;
479 }
480 
481 struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
482     .open = QCamera2Factory::camera_device_open,
483 };
484 
485 /*===========================================================================
486  * FUNCTION   : openLegacy
487  *
488  * DESCRIPTION: Function to open older hal version implementation
489  *
490  * PARAMETERS :
491  *   @camera_id : camera ID
492  *   @halVersion: Based on camera_module_t.common.module_api_version
493  *   @hw_device : ptr to struct storing camera hardware device info
494  *
495  * RETURN     : 0  -- success
496  *              none-zero failure code
497  *==========================================================================*/
498 int QCamera2Factory::openLegacy(
499         int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
500 {
501     int rc = NO_ERROR;
502 
503     LOGI("openLegacy halVersion: %d cameraId = %d", halVersion, cameraId);
504     //Assumption: all cameras can support legacy API version
505     if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
506         return -ENODEV;
507 
508     switch(halVersion)
509     {
510 #ifdef QCAMERA_HAL1_SUPPORT
511         case CAMERA_DEVICE_API_VERSION_1_0:
512         {
513             CAMSCOPE_INIT(CAMSCOPE_SECTION_HAL);
514             QCamera2HardwareInterface *hw =
515                 new QCamera2HardwareInterface((uint32_t)cameraId);
516             if (!hw) {
517                 LOGE("Allocation of hardware interface failed");
518                 return NO_MEMORY;
519             }
520             rc = hw->openCamera(hw_device);
521             if (rc != NO_ERROR) {
522                 delete hw;
523             }
524             break;
525         }
526 #endif
527         default:
528             LOGE("Device API version: %d for camera id %d invalid",
529                  halVersion, cameraId);
530             return BAD_VALUE;
531     }
532 
533     return rc;
534 }
535 
536 /*===========================================================================
537  * FUNCTION   : setTorchMode
538  *
539  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
540  *
541  * PARAMETERS :
542  *   @camera_id : camera ID
543  *   @on        : Indicates whether to turn the flash on or off
544  *
545  * RETURN     : 0  -- success
546  *              none-zero failure code
547  *==========================================================================*/
548 int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
549 {
550     int retVal(0);
551     long cameraIdLong(-1);
552     int cameraIdInt(-1);
553     char* endPointer = NULL;
554     errno = 0;
555     QCameraFlash& flash = QCameraFlash::getInstance();
556 
557     cameraIdLong = strtol(camera_id, &endPointer, 10);
558 
559     if ((errno == ERANGE) ||
560             (cameraIdLong < 0) ||
561             (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
562             (endPointer == camera_id) ||
563             (*endPointer != '\0')) {
564         retVal = -EINVAL;
565     } else if (on) {
566         cameraIdInt = static_cast<int>(cameraIdLong);
567         retVal = flash.initFlash(cameraIdInt);
568 
569         if (retVal == 0) {
570             retVal = flash.setFlashMode(cameraIdInt, on);
571             if ((retVal == 0) && (mCallbacks != NULL)) {
572                 mCallbacks->torch_mode_status_change(mCallbacks,
573                         camera_id,
574                         TORCH_MODE_STATUS_AVAILABLE_ON);
575             } else if (retVal == -EALREADY) {
576                 // Flash is already on, so treat this as a success.
577                 retVal = 0;
578             }
579         }
580     } else {
581         cameraIdInt = static_cast<int>(cameraIdLong);
582         retVal = flash.setFlashMode(cameraIdInt, on);
583 
584         if (retVal == 0) {
585             retVal = flash.deinitFlash(cameraIdInt);
586             if ((retVal == 0) && (mCallbacks != NULL)) {
587                 mCallbacks->torch_mode_status_change(mCallbacks,
588                         camera_id,
589                         TORCH_MODE_STATUS_AVAILABLE_OFF);
590             }
591         } else if (retVal == -EALREADY) {
592             // Flash is already off, so treat this as a success.
593             retVal = 0;
594         }
595     }
596 
597     return retVal;
598 }
599 
600 /*===========================================================================
601  * FUNCTION   : isDualCamAvailable
602  *
603  * DESCRIPTION: Function to check whether we have dual Camera HW available
604  *
605  * PARAMETERS :
606  *   @hal3Enabled : HAL3 enable flag
607  *
608  * RETURN     : bool - true : have Dual Camera HW available
609  *                           false : not have Dual Camera HW available
610  *==========================================================================*/
611 bool QCamera2Factory::isDualCamAvailable(int hal3Enabled)
612 {
613     bool rc = false;
614     int i = 0;
615     camera_info info;
616     cam_sync_type_t cam_type = CAM_TYPE_MAIN;
617 
618     for (i = 0; i < mNumOfCameras; i++) {
619         if (!hal3Enabled) {
620 #ifdef QCAMERA_HAL1_SUPPORT
621             QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
622 #endif
623         }
624 
625         if(cam_type == CAM_TYPE_AUX) {
626             LOGH("Have Dual Camera HW Avaiable.");
627             rc = true;
628             break;
629         }
630     }
631 #ifdef QCAMERA_HAL1_SUPPORT
632     return rc;
633 #else
634     return false;
635 #endif
636 }
637 
638 }; // namespace qcamera
639 
640