1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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 //#define LOG_NDEBUG 0
32
33 #include <stdlib.h>
34 #include <utils/Log.h>
35 #include <utils/Errors.h>
36 #include <hardware/camera.h>
37 #include <hardware/camera3.h>
38
39 #include "HAL/QCamera2HWI.h"
40 #include "HAL3/QCamera3HWI.h"
41 #include "util/QCameraFlash.h"
42 #include "QCamera2Factory.h"
43
44 using namespace android;
45
46 namespace qcamera {
47
48 QCamera2Factory *gQCamera2Factory = NULL;
49
50 /*===========================================================================
51 * FUNCTION : QCamera2Factory
52 *
53 * DESCRIPTION: default constructor of QCamera2Factory
54 *
55 * PARAMETERS : none
56 *
57 * RETURN : None
58 *==========================================================================*/
QCamera2Factory()59 QCamera2Factory::QCamera2Factory()
60 {
61 mHalDescriptors = NULL;
62 mCallbacks = NULL;
63 mNumOfCameras = get_num_of_cameras();
64 char prop[PROPERTY_VALUE_MAX];
65 property_get("persist.camera.HAL3.enabled", prop, "1");
66 int isHAL3Enabled = atoi(prop);
67
68 if ((mNumOfCameras > 0) && (mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
69 mHalDescriptors = new hal_desc[mNumOfCameras];
70 if ( NULL != mHalDescriptors) {
71 uint32_t cameraId = 0;
72
73 for (int i = 0; i < mNumOfCameras ; i++, cameraId++) {
74 mHalDescriptors[i].cameraId = cameraId;
75 if (isHAL3Enabled) {
76 mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_3_0;
77 } else {
78 mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_1_0;
79 }
80 }
81 } else {
82 ALOGE("%s: Not enough resources to allocate HAL descriptor table!",
83 __func__);
84 }
85 } else {
86 ALOGE("%s: %d camera devices detected!", __func__, mNumOfCameras);
87 }
88 }
89
90 /*===========================================================================
91 * FUNCTION : ~QCamera2Factory
92 *
93 * DESCRIPTION: deconstructor of QCamera2Factory
94 *
95 * PARAMETERS : none
96 *
97 * RETURN : None
98 *==========================================================================*/
~QCamera2Factory()99 QCamera2Factory::~QCamera2Factory()
100 {
101 if ( NULL != mHalDescriptors ) {
102 delete [] mHalDescriptors;
103 }
104 }
105
106 /*===========================================================================
107 * FUNCTION : get_number_of_cameras
108 *
109 * DESCRIPTION: static function to query number of cameras detected
110 *
111 * PARAMETERS : none
112 *
113 * RETURN : number of cameras detected
114 *==========================================================================*/
get_number_of_cameras()115 int QCamera2Factory::get_number_of_cameras()
116 {
117 if (!gQCamera2Factory) {
118 gQCamera2Factory = new QCamera2Factory();
119 if (!gQCamera2Factory) {
120 ALOGE("%s: Failed to allocate Camera2Factory object", __func__);
121 return 0;
122 }
123 }
124 return gQCamera2Factory->getNumberOfCameras();
125 }
126
127 /*===========================================================================
128 * FUNCTION : get_camera_info
129 *
130 * DESCRIPTION: static function to query camera information with its ID
131 *
132 * PARAMETERS :
133 * @camera_id : camera ID
134 * @info : ptr to camera info struct
135 *
136 * RETURN : int32_t type of status
137 * NO_ERROR -- success
138 * none-zero failure code
139 *==========================================================================*/
get_camera_info(int camera_id,struct camera_info * info)140 int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
141 {
142 return gQCamera2Factory->getCameraInfo(camera_id, info);
143 }
144
145 /*===========================================================================
146 * FUNCTION : set_callbacks
147 *
148 * DESCRIPTION: static function to set callbacks function to camera module
149 *
150 * PARAMETERS :
151 * @callbacks : ptr to callback functions
152 *
153 * RETURN : NO_ERROR -- success
154 * none-zero failure code
155 *==========================================================================*/
set_callbacks(const camera_module_callbacks_t * callbacks)156 int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
157 {
158 return gQCamera2Factory->setCallbacks(callbacks);
159 }
160
161 /*===========================================================================
162 * FUNCTION : open_legacy
163 *
164 * DESCRIPTION: Function to open older hal version implementation
165 *
166 * PARAMETERS :
167 * @hw_device : ptr to struct storing camera hardware device info
168 * @camera_id : camera ID
169 * @halVersion: Based on camera_module_t.common.module_api_version
170 *
171 * RETURN : 0 -- success
172 * none-zero failure code
173 *==========================================================================*/
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)174 int QCamera2Factory::open_legacy(const struct hw_module_t* module,
175 const char* id, uint32_t halVersion, struct hw_device_t** device)
176 {
177 if (module != &HAL_MODULE_INFO_SYM.common) {
178 ALOGE("Invalid module. Trying to open %p, expect %p",
179 module, &HAL_MODULE_INFO_SYM.common);
180 return INVALID_OPERATION;
181 }
182 if (!id) {
183 ALOGE("Invalid camera id");
184 return BAD_VALUE;
185 }
186 return gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
187 }
188
189 /*===========================================================================
190 * FUNCTION : set_torch_mode
191 *
192 * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
193 *
194 * PARAMETERS :
195 * @camera_id : camera ID
196 * @on : Indicates whether to turn the flash on or off
197 *
198 * RETURN : 0 -- success
199 * none-zero failure code
200 *==========================================================================*/
set_torch_mode(const char * camera_id,bool on)201 int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
202 {
203 return gQCamera2Factory->setTorchMode(camera_id, on);
204 }
205
206 /*===========================================================================
207 * FUNCTION : getNumberOfCameras
208 *
209 * DESCRIPTION: query number of cameras detected
210 *
211 * PARAMETERS : none
212 *
213 * RETURN : number of cameras detected
214 *==========================================================================*/
getNumberOfCameras()215 int QCamera2Factory::getNumberOfCameras()
216 {
217 return mNumOfCameras;
218 }
219
220 /*===========================================================================
221 * FUNCTION : getCameraInfo
222 *
223 * DESCRIPTION: query camera information with its ID
224 *
225 * PARAMETERS :
226 * @camera_id : camera ID
227 * @info : ptr to camera info struct
228 *
229 * RETURN : int32_t type of status
230 * NO_ERROR -- success
231 * none-zero failure code
232 *==========================================================================*/
getCameraInfo(int camera_id,struct camera_info * info)233 int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
234 {
235 int rc;
236 ALOGV("%s: E, camera_id = %d", __func__, camera_id);
237
238 if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
239 (camera_id < 0)) {
240 return -ENODEV;
241 }
242
243 if ( NULL == mHalDescriptors ) {
244 ALOGE("%s : Hal descriptor table is not initialized!", __func__);
245 return NO_INIT;
246 }
247
248 if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
249 rc = QCamera3HardwareInterface::getCamInfo(mHalDescriptors[camera_id].cameraId, info);
250 } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
251 rc = QCamera2HardwareInterface::getCapabilities(mHalDescriptors[camera_id].cameraId, info);
252 } else {
253 ALOGE("%s: Device version for camera id %d invalid %d",
254 __func__,
255 camera_id,
256 mHalDescriptors[camera_id].device_version);
257 return BAD_VALUE;
258 }
259
260 ALOGV("%s: X", __func__);
261 return rc;
262 }
263
264 /*===========================================================================
265 * FUNCTION : setCallbacks
266 *
267 * DESCRIPTION: set callback functions to send asynchronous notifications to
268 * frameworks.
269 *
270 * PARAMETERS :
271 * @callbacks : callback function pointer
272 *
273 * RETURN :
274 * NO_ERROR -- success
275 * none-zero failure code
276 *==========================================================================*/
setCallbacks(const camera_module_callbacks_t * callbacks)277 int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
278 {
279 int rc = NO_ERROR;
280 mCallbacks = callbacks;
281
282 rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
283 if (rc != 0) {
284 ALOGE("%s : Failed to register callbacks with flash module!", __func__);
285 }
286
287 return rc;
288 }
289
290 /*===========================================================================
291 * FUNCTION : cameraDeviceOpen
292 *
293 * DESCRIPTION: open a camera device with its ID
294 *
295 * PARAMETERS :
296 * @camera_id : camera ID
297 * @hw_device : ptr to struct storing camera hardware device info
298 *
299 * RETURN : int32_t type of status
300 * NO_ERROR -- success
301 * none-zero failure code
302 *==========================================================================*/
cameraDeviceOpen(int camera_id,struct hw_device_t ** hw_device)303 int QCamera2Factory::cameraDeviceOpen(int camera_id,
304 struct hw_device_t **hw_device)
305 {
306 int rc = NO_ERROR;
307 if (camera_id < 0 || camera_id >= mNumOfCameras)
308 return -ENODEV;
309
310 if ( NULL == mHalDescriptors ) {
311 ALOGE("%s : Hal descriptor table is not initialized!", __func__);
312 return NO_INIT;
313 }
314
315 if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
316 QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
317 mCallbacks);
318 if (!hw) {
319 ALOGE("Allocation of hardware interface failed");
320 return NO_MEMORY;
321 }
322 rc = hw->openCamera(hw_device);
323 if (rc != 0) {
324 delete hw;
325 }
326 } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
327 QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
328 if (!hw) {
329 ALOGE("Allocation of hardware interface failed");
330 return NO_MEMORY;
331 }
332 rc = hw->openCamera(hw_device);
333 if (rc != NO_ERROR) {
334 delete hw;
335 }
336 } else {
337 ALOGE("%s: Device version for camera id %d invalid %d",
338 __func__,
339 camera_id,
340 mHalDescriptors[camera_id].device_version);
341 return BAD_VALUE;
342 }
343
344 return rc;
345 }
346
347 /*===========================================================================
348 * FUNCTION : camera_device_open
349 *
350 * DESCRIPTION: static function to open a camera device by its ID
351 *
352 * PARAMETERS :
353 * @camera_id : camera ID
354 * @hw_device : ptr to struct storing camera hardware device info
355 *
356 * RETURN : int32_t type of status
357 * NO_ERROR -- success
358 * none-zero failure code
359 *==========================================================================*/
camera_device_open(const struct hw_module_t * module,const char * id,struct hw_device_t ** hw_device)360 int QCamera2Factory::camera_device_open(
361 const struct hw_module_t *module, const char *id,
362 struct hw_device_t **hw_device)
363 {
364 if (module != &HAL_MODULE_INFO_SYM.common) {
365 ALOGE("Invalid module. Trying to open %p, expect %p",
366 module, &HAL_MODULE_INFO_SYM.common);
367 return INVALID_OPERATION;
368 }
369 if (!id) {
370 ALOGE("Invalid camera id");
371 return BAD_VALUE;
372 }
373 return gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
374 }
375
376 struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
377 open: QCamera2Factory::camera_device_open,
378 };
379
380 /*===========================================================================
381 * FUNCTION : openLegacy
382 *
383 * DESCRIPTION: Function to open older hal version implementation
384 *
385 * PARAMETERS :
386 * @camera_id : camera ID
387 * @halVersion: Based on camera_module_t.common.module_api_version
388 * @hw_device : ptr to struct storing camera hardware device info
389 *
390 * RETURN : 0 -- success
391 * none-zero failure code
392 *==========================================================================*/
openLegacy(int32_t cameraId,uint32_t halVersion,struct hw_device_t ** hw_device)393 int QCamera2Factory::openLegacy(
394 int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
395 {
396 int rc = NO_ERROR;
397
398 ALOGI(":%s openLegacy halVersion: %d", __func__, halVersion);
399 //Assumption: all cameras can support legacy API version
400 if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
401 return -ENODEV;
402
403 switch(halVersion)
404 {
405 case CAMERA_DEVICE_API_VERSION_1_0:
406 {
407 QCamera2HardwareInterface *hw =
408 new QCamera2HardwareInterface((uint32_t)cameraId);
409 if (!hw) {
410 ALOGE("%s: Allocation of hardware interface failed", __func__);
411 return NO_MEMORY;
412 }
413 rc = hw->openCamera(hw_device);
414 if (rc != NO_ERROR) {
415 delete hw;
416 }
417 break;
418 }
419 default:
420 ALOGE("%s: Device API version: %d for camera id %d invalid",
421 __func__, halVersion, cameraId);
422 return BAD_VALUE;
423 }
424
425 return rc;
426 }
427
428 /*===========================================================================
429 * FUNCTION : setTorchMode
430 *
431 * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
432 *
433 * PARAMETERS :
434 * @camera_id : camera ID
435 * @on : Indicates whether to turn the flash on or off
436 *
437 * RETURN : 0 -- success
438 * none-zero failure code
439 *==========================================================================*/
setTorchMode(const char * camera_id,bool on)440 int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
441 {
442 int retVal(0);
443 long cameraIdLong(-1);
444 int cameraIdInt(-1);
445 char* endPointer = NULL;
446 errno = 0;
447 QCameraFlash& flash = QCameraFlash::getInstance();
448
449 cameraIdLong = strtol(camera_id, &endPointer, 10);
450
451 if ((errno == ERANGE) ||
452 (cameraIdLong < 0) ||
453 (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
454 (endPointer == camera_id) ||
455 (*endPointer != '\0')) {
456 retVal = -EINVAL;
457 } else if (on) {
458 cameraIdInt = static_cast<int>(cameraIdLong);
459 retVal = flash.initFlash(cameraIdInt);
460
461 if (retVal == 0) {
462 retVal = flash.setFlashMode(cameraIdInt, on);
463 if ((retVal == 0) && (mCallbacks != NULL)) {
464 mCallbacks->torch_mode_status_change(mCallbacks,
465 camera_id,
466 TORCH_MODE_STATUS_AVAILABLE_ON);
467 } else if (retVal == -EALREADY) {
468 // Flash is already on, so treat this as a success.
469 retVal = 0;
470 }
471 }
472 } else {
473 cameraIdInt = static_cast<int>(cameraIdLong);
474 retVal = flash.setFlashMode(cameraIdInt, on);
475
476 if (retVal == 0) {
477 retVal = flash.deinitFlash(cameraIdInt);
478 if ((retVal == 0) && (mCallbacks != NULL)) {
479 mCallbacks->torch_mode_status_change(mCallbacks,
480 camera_id,
481 TORCH_MODE_STATUS_AVAILABLE_OFF);
482 }
483 } else if (retVal == -EALREADY) {
484 // Flash is already off, so treat this as a success.
485 retVal = 0;
486 }
487 }
488
489 return retVal;
490 }
491
492 }; // namespace qcamera
493
494