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