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