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