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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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 *==========================================================================*/ 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