• 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 
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 
45 extern "C" {
46 #include "mm_camera_dbg.h"
47 }
48 
49 using namespace android;
50 
51 namespace qcamera {
52 
53 QCamera2Factory *gQCamera2Factory = NULL;
54 QCameraMuxer *gQCameraMuxer = NULL;
55 pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
56 //Total number of cameras opened simultaneously.
57 //This variable updation is protected by gCamLock.
58 uint8_t gNumCameraSessions = 0;
59 
60 volatile 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  *==========================================================================*/
QCamera2Factory()71 QCamera2Factory::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  *==========================================================================*/
~QCamera2Factory()136 QCamera2Factory::~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  *==========================================================================*/
get_number_of_cameras()156 int 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  *==========================================================================*/
get_camera_info(int camera_id,struct camera_info * info)190 int 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  *==========================================================================*/
set_callbacks(const camera_module_callbacks_t * callbacks)213 int 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  *==========================================================================*/
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)237 int 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  *==========================================================================*/
set_torch_mode(const char * camera_id,bool on)270 int 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  *==========================================================================*/
getNumberOfCameras()284 int 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  *==========================================================================*/
getCameraInfo(int camera_id,struct camera_info * info)302 int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
303 {
304     int rc;
305 
306     if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
307         (camera_id < 0)) {
308         LOGE("Error getting camera info!! mNumOfCameras = %d,"
309                 "camera_id = %d, info = %p",
310                  mNumOfCameras, camera_id, info);
311         return -ENODEV;
312     }
313 
314     if ( NULL == mHalDescriptors ) {
315         LOGE("Hal descriptor table is not initialized!");
316         return NO_INIT;
317     }
318 
319     LOGI("Camera id %d API version %d",
320             camera_id, mHalDescriptors[camera_id].device_version);
321 
322     // Need ANDROID_FLASH_INFO_AVAILABLE property for flashlight widget to
323     // work and so get the static data regardless of HAL version
324     rc = QCamera3HardwareInterface::getCamInfo(
325             mHalDescriptors[camera_id].cameraId, info);
326     if (mHalDescriptors[camera_id].device_version ==
327             CAMERA_DEVICE_API_VERSION_1_0) {
328         info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
329     }
330 
331     return rc;
332 }
333 
334 /*===========================================================================
335  * FUNCTION   : setCallbacks
336  *
337  * DESCRIPTION: set callback functions to send asynchronous notifications to
338  *              frameworks.
339  *
340  * PARAMETERS :
341  *   @callbacks : callback function pointer
342  *
343  * RETURN     :
344  *              NO_ERROR  -- success
345  *              none-zero failure code
346  *==========================================================================*/
setCallbacks(const camera_module_callbacks_t * callbacks)347 int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
348 {
349     int rc = NO_ERROR;
350     mCallbacks = callbacks;
351 
352     rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
353     if (rc != 0) {
354         LOGE("Failed to register callbacks with flash module!");
355     }
356 
357     return rc;
358 }
359 
360 /*===========================================================================
361  * FUNCTION   : cameraDeviceOpen
362  *
363  * DESCRIPTION: open a camera device with its ID
364  *
365  * PARAMETERS :
366  *   @camera_id : camera ID
367  *   @hw_device : ptr to struct storing camera hardware device info
368  *
369  * RETURN     : int32_t type of status
370  *              NO_ERROR  -- success
371  *              none-zero failure code
372  *==========================================================================*/
cameraDeviceOpen(int camera_id,struct hw_device_t ** hw_device)373 int QCamera2Factory::cameraDeviceOpen(int camera_id,
374                     struct hw_device_t **hw_device)
375 {
376     int rc = NO_ERROR;
377     if (camera_id < 0 || camera_id >= mNumOfCameras)
378         return -ENODEV;
379 
380     if ( NULL == mHalDescriptors ) {
381         LOGE("Hal descriptor table is not initialized!");
382         return NO_INIT;
383     }
384 
385     LOGI("Open camera id %d API version %d",
386             camera_id, mHalDescriptors[camera_id].device_version);
387 
388     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
389         QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
390                 mCallbacks);
391         if (!hw) {
392             LOGE("Allocation of hardware interface failed");
393             return NO_MEMORY;
394         }
395         rc = hw->openCamera(hw_device);
396         if (rc != 0) {
397             delete hw;
398         }
399     } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
400         QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
401         if (!hw) {
402             LOGE("Allocation of hardware interface failed");
403             return NO_MEMORY;
404         }
405         rc = hw->openCamera(hw_device);
406         if (rc != NO_ERROR) {
407             delete hw;
408         }
409     } else {
410         LOGE("Device version for camera id %d invalid %d",
411               camera_id,
412               mHalDescriptors[camera_id].device_version);
413         return BAD_VALUE;
414     }
415 
416     return rc;
417 }
418 
419 /*===========================================================================
420  * FUNCTION   : camera_device_open
421  *
422  * DESCRIPTION: static function to open a camera device by its ID
423  *
424  * PARAMETERS :
425  *   @camera_id : camera ID
426  *   @hw_device : ptr to struct storing camera hardware device info
427  *
428  * RETURN     : int32_t type of status
429  *              NO_ERROR  -- success
430  *              none-zero failure code
431  *==========================================================================*/
camera_device_open(const struct hw_module_t * module,const char * id,struct hw_device_t ** hw_device)432 int QCamera2Factory::camera_device_open(
433     const struct hw_module_t *module, const char *id,
434     struct hw_device_t **hw_device)
435 {
436     int rc = NO_ERROR;
437     if (module != &HAL_MODULE_INFO_SYM.common) {
438         LOGE("Invalid module. Trying to open %p, expect %p",
439             module, &HAL_MODULE_INFO_SYM.common);
440         return INVALID_OPERATION;
441     }
442     if (!id) {
443         LOGE("Invalid camera id");
444         return BAD_VALUE;
445     }
446 
447     if(gQCameraMuxer)
448         rc =  gQCameraMuxer->camera_device_open(module, id, hw_device);
449     else
450         rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
451 
452     return rc;
453 }
454 
455 struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
456     .open = QCamera2Factory::camera_device_open,
457 };
458 
459 /*===========================================================================
460  * FUNCTION   : openLegacy
461  *
462  * DESCRIPTION: Function to open older hal version implementation
463  *
464  * PARAMETERS :
465  *   @camera_id : camera ID
466  *   @halVersion: Based on camera_module_t.common.module_api_version
467  *   @hw_device : ptr to struct storing camera hardware device info
468  *
469  * RETURN     : 0  -- success
470  *              none-zero failure code
471  *==========================================================================*/
openLegacy(int32_t cameraId,uint32_t halVersion,struct hw_device_t ** hw_device)472 int QCamera2Factory::openLegacy(
473         int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
474 {
475     int rc = NO_ERROR;
476 
477     LOGI("openLegacy halVersion: %d", halVersion);
478     //Assumption: all cameras can support legacy API version
479     if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
480         return -ENODEV;
481 
482     switch(halVersion)
483     {
484         case CAMERA_DEVICE_API_VERSION_1_0:
485         {
486             QCamera2HardwareInterface *hw =
487                 new QCamera2HardwareInterface((uint32_t)cameraId);
488             if (!hw) {
489                 LOGE("Allocation of hardware interface failed");
490                 return NO_MEMORY;
491             }
492             rc = hw->openCamera(hw_device);
493             if (rc != NO_ERROR) {
494                 delete hw;
495             }
496             break;
497         }
498         default:
499             LOGE("Device API version: %d for camera id %d invalid",
500                  halVersion, cameraId);
501             return BAD_VALUE;
502     }
503 
504     return rc;
505 }
506 
507 /*===========================================================================
508  * FUNCTION   : setTorchMode
509  *
510  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
511  *
512  * PARAMETERS :
513  *   @camera_id : camera ID
514  *   @on        : Indicates whether to turn the flash on or off
515  *
516  * RETURN     : 0  -- success
517  *              none-zero failure code
518  *==========================================================================*/
setTorchMode(const char * camera_id,bool on)519 int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
520 {
521     int retVal(0);
522     long cameraIdLong(-1);
523     int cameraIdInt(-1);
524     char* endPointer = NULL;
525     errno = 0;
526     QCameraFlash& flash = QCameraFlash::getInstance();
527 
528     cameraIdLong = strtol(camera_id, &endPointer, 10);
529 
530     if ((errno == ERANGE) ||
531             (cameraIdLong < 0) ||
532             (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
533             (endPointer == camera_id) ||
534             (*endPointer != '\0')) {
535         retVal = -EINVAL;
536     } else if (on) {
537         cameraIdInt = static_cast<int>(cameraIdLong);
538         retVal = flash.initFlash(cameraIdInt);
539 
540         if (retVal == 0) {
541             retVal = flash.setFlashMode(cameraIdInt, on);
542             if ((retVal == 0) && (mCallbacks != NULL)) {
543                 mCallbacks->torch_mode_status_change(mCallbacks,
544                         camera_id,
545                         TORCH_MODE_STATUS_AVAILABLE_ON);
546             } else if (retVal == -EALREADY) {
547                 // Flash is already on, so treat this as a success.
548                 retVal = 0;
549             }
550         }
551     } else {
552         cameraIdInt = static_cast<int>(cameraIdLong);
553         retVal = flash.setFlashMode(cameraIdInt, on);
554 
555         if (retVal == 0) {
556             retVal = flash.deinitFlash(cameraIdInt);
557             if ((retVal == 0) && (mCallbacks != NULL)) {
558                 mCallbacks->torch_mode_status_change(mCallbacks,
559                         camera_id,
560                         TORCH_MODE_STATUS_AVAILABLE_OFF);
561             }
562         } else if (retVal == -EALREADY) {
563             // Flash is already off, so treat this as a success.
564             retVal = 0;
565         }
566     }
567 
568     return retVal;
569 }
570 
571 /*===========================================================================
572  * FUNCTION   : isDualCamAvailable
573  *
574  * DESCRIPTION: Function to check whether we have dual Camera HW available
575  *
576  * PARAMETERS :
577  *   @hal3Enabled : HAL3 enable flag
578  *
579  * RETURN     : bool - true : have Dual Camera HW available
580  *                           false : not have Dual Camera HW available
581  *==========================================================================*/
isDualCamAvailable(int hal3Enabled)582 bool QCamera2Factory::isDualCamAvailable(int hal3Enabled)
583 {
584     bool rc = FALSE;
585     int i = 0;
586     camera_info info;
587     cam_sync_type_t cam_type = CAM_TYPE_MAIN;
588 
589     for (i = 0; i < mNumOfCameras; i++) {
590         if (!hal3Enabled) {
591             QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
592         }
593 
594         if(cam_type == CAM_TYPE_AUX) {
595             LOGH("Have Dual Camera HW Avaiable.");
596             rc = TRUE;
597             break;
598         }
599     }
600 
601     return rc;
602 }
603 
604 }; // namespace qcamera
605 
606