• 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     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