• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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