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