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