CameraFlashlight.cpp revision cc776718c0be7c31fe5ab4fc1446d377be60369f
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "CameraFlashlight" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19// #define LOG_NDEBUG 0 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23#include <cutils/properties.h> 24 25#include "camera/CameraMetadata.h" 26#include "CameraFlashlight.h" 27#include "gui/IGraphicBufferConsumer.h" 28#include "gui/BufferQueue.h" 29#include "camera/camera2/CaptureRequest.h" 30#include "CameraDeviceFactory.h" 31 32 33namespace android { 34 35///////////////////////////////////////////////////////////////////// 36// CameraFlashlight implementation begins 37// used by camera service to control flashflight. 38///////////////////////////////////////////////////////////////////// 39CameraFlashlight::CameraFlashlight(CameraModule& cameraModule, 40 const camera_module_callbacks_t& callbacks) : 41 mCameraModule(&cameraModule), 42 mCallbacks(&callbacks), 43 mFlashlightMapInitialized(false) { 44} 45 46CameraFlashlight::~CameraFlashlight() { 47} 48 49status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { 50 ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__, 51 cameraId.string()); 52 if (mFlashControl != NULL) { 53 return INVALID_OPERATION; 54 } 55 56 status_t res = OK; 57 58 if (mCameraModule->getRawModule()->module_api_version >= 59 CAMERA_MODULE_API_VERSION_2_4) { 60 mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks); 61 if (mFlashControl == NULL) { 62 ALOGV("%s: cannot create flash control for module api v2.4+", 63 __FUNCTION__); 64 return NO_MEMORY; 65 } 66 } else { 67 uint32_t deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; 68 69 if (mCameraModule->getRawModule()->module_api_version >= 70 CAMERA_MODULE_API_VERSION_2_0) { 71 camera_info info; 72 res = mCameraModule->getCameraInfo( 73 atoi(String8(cameraId).string()), &info); 74 if (res) { 75 ALOGE("%s: failed to get camera info for camera %s", 76 __FUNCTION__, cameraId.string()); 77 return res; 78 } 79 deviceVersion = info.device_version; 80 } 81 82 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) { 83 CameraDeviceClientFlashControl *flashControl = 84 new CameraDeviceClientFlashControl(*mCameraModule, 85 *mCallbacks); 86 if (!flashControl) { 87 return NO_MEMORY; 88 } 89 90 mFlashControl = flashControl; 91 } else { 92 mFlashControl = 93 new CameraHardwareInterfaceFlashControl(*mCameraModule, 94 *mCallbacks); 95 } 96 } 97 98 return OK; 99} 100 101status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) { 102 if (!mFlashlightMapInitialized) { 103 ALOGE("%s: findFlashUnits() must be called before this method."); 104 return NO_INIT; 105 } 106 107 ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__, 108 cameraId.string(), enabled); 109 110 status_t res = OK; 111 Mutex::Autolock l(mLock); 112 113 if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) { 114 // This case is needed to avoid state corruption during the following call sequence: 115 // CameraService::setTorchMode for camera ID 0 begins, does torch status checks 116 // CameraService::connect for camera ID 0 begins, calls prepareDeviceOpen, ends 117 // CameraService::setTorchMode for camera ID 0 continues, calls 118 // CameraFlashlight::setTorchMode 119 120 // TODO: Move torch status checks and state updates behind this CameraFlashlight lock 121 // to avoid other similar race conditions. 122 ALOGE("%s: Camera device %s is in use, cannot set torch mode.", 123 __FUNCTION__, cameraId.string()); 124 return -EBUSY; 125 } 126 127 if (mFlashControl == NULL) { 128 if (enabled == false) { 129 return OK; 130 } 131 132 res = createFlashlightControl(cameraId); 133 if (res) { 134 return res; 135 } 136 res = mFlashControl->setTorchMode(cameraId, enabled); 137 return res; 138 } 139 140 // if flash control already exists, turning on torch mode may fail if it's 141 // tied to another camera device for module v2.3 and below. 142 res = mFlashControl->setTorchMode(cameraId, enabled); 143 if (res == BAD_INDEX) { 144 // flash control is tied to another camera device, need to close it and 145 // try again. 146 mFlashControl.clear(); 147 res = createFlashlightControl(cameraId); 148 if (res) { 149 return res; 150 } 151 res = mFlashControl->setTorchMode(cameraId, enabled); 152 } 153 154 return res; 155} 156 157status_t CameraFlashlight::findFlashUnits() { 158 Mutex::Autolock l(mLock); 159 status_t res; 160 int32_t numCameras = mCameraModule->getNumberOfCameras(); 161 162 mHasFlashlightMap.clear(); 163 mFlashlightMapInitialized = false; 164 165 for (int32_t i = 0; i < numCameras; i++) { 166 bool hasFlash = false; 167 String8 id = String8::format("%d", i); 168 169 res = createFlashlightControl(id); 170 if (res) { 171 ALOGE("%s: failed to create flash control for %s", __FUNCTION__, 172 id.string()); 173 } else { 174 res = mFlashControl->hasFlashUnit(id, &hasFlash); 175 if (res == -EUSERS || res == -EBUSY) { 176 ALOGE("%s: failed to check if camera %s has a flash unit. Some " 177 "camera devices may be opened", __FUNCTION__, 178 id.string()); 179 return res; 180 } else if (res) { 181 ALOGE("%s: failed to check if camera %s has a flash unit. %s" 182 " (%d)", __FUNCTION__, id.string(), strerror(-res), 183 res); 184 } 185 186 mFlashControl.clear(); 187 } 188 mHasFlashlightMap.add(id, hasFlash); 189 } 190 191 mFlashlightMapInitialized = true; 192 return OK; 193} 194 195bool CameraFlashlight::hasFlashUnit(const String8& cameraId) { 196 status_t res; 197 198 Mutex::Autolock l(mLock); 199 return hasFlashUnitLocked(cameraId); 200} 201 202bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) { 203 if (!mFlashlightMapInitialized) { 204 ALOGE("%s: findFlashUnits() must be called before this method."); 205 return false; 206 } 207 208 ssize_t index = mHasFlashlightMap.indexOfKey(cameraId); 209 if (index == NAME_NOT_FOUND) { 210 ALOGE("%s: camera %s not present when findFlashUnits() was called", 211 __FUNCTION__, cameraId.string()); 212 return false; 213 } 214 215 return mHasFlashlightMap.valueAt(index); 216} 217 218status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) { 219 ALOGV("%s: prepare for device open", __FUNCTION__); 220 221 Mutex::Autolock l(mLock); 222 if (!mFlashlightMapInitialized) { 223 ALOGE("%s: findFlashUnits() must be called before this method."); 224 return NO_INIT; 225 } 226 227 if (mCameraModule->getRawModule()->module_api_version < 228 CAMERA_MODULE_API_VERSION_2_4) { 229 // framework is going to open a camera device, all flash light control 230 // should be closed for backward compatible support. 231 mFlashControl.clear(); 232 233 if (mOpenedCameraIds.size() == 0) { 234 // notify torch unavailable for all cameras with a flash 235 int numCameras = mCameraModule->getNumberOfCameras(); 236 for (int i = 0; i < numCameras; i++) { 237 if (hasFlashUnitLocked(String8::format("%d", i))) { 238 mCallbacks->torch_mode_status_change(mCallbacks, 239 String8::format("%d", i).string(), 240 TORCH_MODE_STATUS_NOT_AVAILABLE); 241 } 242 } 243 } 244 245 // close flash control that may be opened by calling hasFlashUnitLocked. 246 mFlashControl.clear(); 247 } 248 249 if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) { 250 mOpenedCameraIds.add(cameraId); 251 } 252 253 return OK; 254} 255 256status_t CameraFlashlight::deviceClosed(const String8& cameraId) { 257 ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string()); 258 259 Mutex::Autolock l(mLock); 260 if (!mFlashlightMapInitialized) { 261 ALOGE("%s: findFlashUnits() must be called before this method."); 262 return NO_INIT; 263 } 264 265 ssize_t index = mOpenedCameraIds.indexOf(cameraId); 266 if (index == NAME_NOT_FOUND) { 267 ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__, 268 cameraId.string()); 269 } else { 270 mOpenedCameraIds.removeAt(index); 271 } 272 273 // Cannot do anything until all cameras are closed. 274 if (mOpenedCameraIds.size() != 0) 275 return OK; 276 277 if (mCameraModule->getRawModule()->module_api_version < 278 CAMERA_MODULE_API_VERSION_2_4) { 279 // notify torch available for all cameras with a flash 280 int numCameras = mCameraModule->getNumberOfCameras(); 281 for (int i = 0; i < numCameras; i++) { 282 if (hasFlashUnitLocked(String8::format("%d", i))) { 283 mCallbacks->torch_mode_status_change(mCallbacks, 284 String8::format("%d", i).string(), 285 TORCH_MODE_STATUS_AVAILABLE_OFF); 286 } 287 } 288 } 289 290 return OK; 291} 292// CameraFlashlight implementation ends 293 294 295FlashControlBase::~FlashControlBase() { 296} 297 298///////////////////////////////////////////////////////////////////// 299// ModuleFlashControl implementation begins 300// Flash control for camera module v2.4 and above. 301///////////////////////////////////////////////////////////////////// 302ModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule, 303 const camera_module_callbacks_t& callbacks) : 304 mCameraModule(&cameraModule) { 305} 306 307ModuleFlashControl::~ModuleFlashControl() { 308} 309 310status_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) { 311 if (!hasFlash) { 312 return BAD_VALUE; 313 } 314 315 *hasFlash = false; 316 Mutex::Autolock l(mLock); 317 318 camera_info info; 319 status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), 320 &info); 321 if (res != 0) { 322 return res; 323 } 324 325 CameraMetadata metadata; 326 metadata = info.static_camera_characteristics; 327 camera_metadata_entry flashAvailable = 328 metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 329 if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 330 *hasFlash = true; 331 } 332 333 return OK; 334} 335 336status_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) { 337 ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__, 338 cameraId.string(), enabled); 339 340 Mutex::Autolock l(mLock); 341 return mCameraModule->setTorchMode(cameraId.string(), enabled); 342} 343// ModuleFlashControl implementation ends 344 345///////////////////////////////////////////////////////////////////// 346// CameraDeviceClientFlashControl implementation begins 347// Flash control for camera module <= v2.3 and camera HAL v2-v3 348///////////////////////////////////////////////////////////////////// 349CameraDeviceClientFlashControl::CameraDeviceClientFlashControl( 350 CameraModule& cameraModule, 351 const camera_module_callbacks_t& callbacks) : 352 mCameraModule(&cameraModule), 353 mCallbacks(&callbacks), 354 mTorchEnabled(false), 355 mMetadata(NULL), 356 mStreaming(false) { 357} 358 359CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { 360 disconnectCameraDevice(); 361 if (mMetadata) { 362 delete mMetadata; 363 } 364 365 mAnw.clear(); 366 mSurfaceTexture.clear(); 367 mProducer.clear(); 368 mConsumer.clear(); 369 370 if (mTorchEnabled) { 371 if (mCallbacks) { 372 ALOGV("%s: notify the framework that torch was turned off", 373 __FUNCTION__); 374 mCallbacks->torch_mode_status_change(mCallbacks, 375 mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 376 } 377 } 378} 379 380status_t CameraDeviceClientFlashControl::initializeSurface( 381 sp<CameraDeviceBase> &device, int32_t width, int32_t height) { 382 status_t res; 383 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 384 385 mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 386 true, true); 387 if (mSurfaceTexture == NULL) { 388 return NO_MEMORY; 389 } 390 391 int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 392 res = mSurfaceTexture->setDefaultBufferSize(width, height); 393 if (res) { 394 return res; 395 } 396 res = mSurfaceTexture->setDefaultBufferFormat(format); 397 if (res) { 398 return res; 399 } 400 401 mAnw = new Surface(mProducer, /*useAsync*/ true); 402 if (mAnw == NULL) { 403 return NO_MEMORY; 404 } 405 res = device->createStream(mAnw, width, height, format, &mStreamId); 406 if (res) { 407 return res; 408 } 409 410 res = device->configureStreams(); 411 if (res) { 412 return res; 413 } 414 415 return res; 416} 417 418status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( 419 const camera_info& info, int32_t *width, int32_t *height) { 420 if (!width || !height) { 421 return BAD_VALUE; 422 } 423 424 int32_t w = INT32_MAX; 425 int32_t h = 1; 426 427 CameraMetadata metadata; 428 metadata = info.static_camera_characteristics; 429 camera_metadata_entry streamConfigs = 430 metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); 431 for (size_t i = 0; i < streamConfigs.count; i += 4) { 432 int32_t fmt = streamConfigs.data.i32[i]; 433 if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) { 434 int32_t ww = streamConfigs.data.i32[i + 1]; 435 int32_t hh = streamConfigs.data.i32[i + 2]; 436 437 if (w * h > ww * hh) { 438 w = ww; 439 h = hh; 440 } 441 } 442 } 443 444 // if stream configuration is not found, try available processed sizes. 445 if (streamConfigs.count == 0) { 446 camera_metadata_entry availableProcessedSizes = 447 metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES); 448 for (size_t i = 0; i < availableProcessedSizes.count; i += 2) { 449 int32_t ww = availableProcessedSizes.data.i32[i]; 450 int32_t hh = availableProcessedSizes.data.i32[i + 1]; 451 if (w * h > ww * hh) { 452 w = ww; 453 h = hh; 454 } 455 } 456 } 457 458 if (w == INT32_MAX) { 459 return NAME_NOT_FOUND; 460 } 461 462 *width = w; 463 *height = h; 464 465 return OK; 466} 467 468status_t CameraDeviceClientFlashControl::connectCameraDevice( 469 const String8& cameraId) { 470 camera_info info; 471 status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); 472 if (res != 0) { 473 ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 474 cameraId.string()); 475 return res; 476 } 477 478 sp<CameraDeviceBase> device = 479 CameraDeviceFactory::createDevice(atoi(cameraId.string())); 480 if (device == NULL) { 481 return NO_MEMORY; 482 } 483 484 res = device->initialize(mCameraModule); 485 if (res) { 486 return res; 487 } 488 489 int32_t width, height; 490 res = getSmallestSurfaceSize(info, &width, &height); 491 if (res) { 492 return res; 493 } 494 res = initializeSurface(device, width, height); 495 if (res) { 496 return res; 497 } 498 499 mCameraId = cameraId; 500 mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1); 501 mDevice = device; 502 503 return OK; 504} 505 506status_t CameraDeviceClientFlashControl::disconnectCameraDevice() { 507 if (mDevice != NULL) { 508 mDevice->disconnect(); 509 mDevice.clear(); 510 } 511 512 return OK; 513} 514 515 516 517status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId, 518 bool *hasFlash) { 519 ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, 520 cameraId.string()); 521 522 Mutex::Autolock l(mLock); 523 return hasFlashUnitLocked(cameraId, hasFlash); 524 525} 526 527status_t CameraDeviceClientFlashControl::hasFlashUnitLocked( 528 const String8& cameraId, bool *hasFlash) { 529 if (!hasFlash) { 530 return BAD_VALUE; 531 } 532 533 camera_info info; 534 status_t res = mCameraModule->getCameraInfo( 535 atoi(cameraId.string()), &info); 536 if (res != 0) { 537 ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 538 cameraId.string()); 539 return res; 540 } 541 542 CameraMetadata metadata; 543 metadata = info.static_camera_characteristics; 544 camera_metadata_entry flashAvailable = 545 metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 546 if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 547 *hasFlash = true; 548 } 549 550 return OK; 551} 552 553status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() { 554 status_t res; 555 556 if (mMetadata == NULL) { 557 mMetadata = new CameraMetadata(); 558 if (mMetadata == NULL) { 559 return NO_MEMORY; 560 } 561 res = mDevice->createDefaultRequest( 562 CAMERA3_TEMPLATE_PREVIEW, mMetadata); 563 if (res) { 564 return res; 565 } 566 } 567 568 uint8_t torchOn = ANDROID_FLASH_MODE_TORCH; 569 mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); 570 mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); 571 572 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; 573 mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); 574 575 int32_t requestId = 0; 576 mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); 577 578 if (mStreaming) { 579 res = mDevice->setStreamingRequest(*mMetadata); 580 } else { 581 res = mDevice->capture(*mMetadata); 582 } 583 return res; 584} 585 586 587 588 589status_t CameraDeviceClientFlashControl::setTorchMode( 590 const String8& cameraId, bool enabled) { 591 bool hasFlash = false; 592 593 Mutex::Autolock l(mLock); 594 status_t res = hasFlashUnitLocked(cameraId, &hasFlash); 595 596 // pre-check 597 if (enabled) { 598 // invalid camera? 599 if (res) { 600 return -EINVAL; 601 } 602 // no flash unit? 603 if (!hasFlash) { 604 return -ENOSYS; 605 } 606 // already opened for a different device? 607 if (mDevice != NULL && cameraId != mCameraId) { 608 return BAD_INDEX; 609 } 610 } else if (mDevice == NULL || cameraId != mCameraId) { 611 // disabling the torch mode of an un-opened or different device. 612 return OK; 613 } else { 614 // disabling the torch mode of currently opened device 615 disconnectCameraDevice(); 616 mTorchEnabled = false; 617 mCallbacks->torch_mode_status_change(mCallbacks, 618 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 619 return OK; 620 } 621 622 if (mDevice == NULL) { 623 res = connectCameraDevice(cameraId); 624 if (res) { 625 return res; 626 } 627 } 628 629 res = submitTorchEnabledRequest(); 630 if (res) { 631 return res; 632 } 633 634 mTorchEnabled = true; 635 mCallbacks->torch_mode_status_change(mCallbacks, 636 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 637 return OK; 638} 639// CameraDeviceClientFlashControl implementation ends 640 641 642///////////////////////////////////////////////////////////////////// 643// CameraHardwareInterfaceFlashControl implementation begins 644// Flash control for camera module <= v2.3 and camera HAL v1 645///////////////////////////////////////////////////////////////////// 646CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( 647 CameraModule& cameraModule, 648 const camera_module_callbacks_t& callbacks) : 649 mCameraModule(&cameraModule), 650 mCallbacks(&callbacks), 651 mTorchEnabled(false) { 652 653} 654 655CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { 656 disconnectCameraDevice(); 657 658 mAnw.clear(); 659 mSurfaceTexture.clear(); 660 mProducer.clear(); 661 mConsumer.clear(); 662 663 if (mTorchEnabled) { 664 if (mCallbacks) { 665 ALOGV("%s: notify the framework that torch was turned off", 666 __FUNCTION__); 667 mCallbacks->torch_mode_status_change(mCallbacks, 668 mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 669 } 670 } 671} 672 673status_t CameraHardwareInterfaceFlashControl::setTorchMode( 674 const String8& cameraId, bool enabled) { 675 Mutex::Autolock l(mLock); 676 677 // pre-check 678 status_t res; 679 if (enabled) { 680 bool hasFlash = false; 681 res = hasFlashUnitLocked(cameraId, &hasFlash); 682 // invalid camera? 683 if (res) { 684 // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to 685 // another camera device. 686 return res == BAD_INDEX ? BAD_INDEX : -EINVAL; 687 } 688 // no flash unit? 689 if (!hasFlash) { 690 return -ENOSYS; 691 } 692 } else if (mDevice == NULL || cameraId != mCameraId) { 693 // disabling the torch mode of an un-opened or different device. 694 return OK; 695 } else { 696 // disabling the torch mode of currently opened device 697 disconnectCameraDevice(); 698 mTorchEnabled = false; 699 mCallbacks->torch_mode_status_change(mCallbacks, 700 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 701 return OK; 702 } 703 704 res = startPreviewAndTorch(); 705 if (res) { 706 return res; 707 } 708 709 mTorchEnabled = true; 710 mCallbacks->torch_mode_status_change(mCallbacks, 711 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 712 return OK; 713} 714 715status_t CameraHardwareInterfaceFlashControl::hasFlashUnit( 716 const String8& cameraId, bool *hasFlash) { 717 Mutex::Autolock l(mLock); 718 return hasFlashUnitLocked(cameraId, hasFlash); 719} 720 721status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( 722 const String8& cameraId, bool *hasFlash) { 723 if (!hasFlash) { 724 return BAD_VALUE; 725 } 726 727 status_t res; 728 if (mDevice == NULL) { 729 res = connectCameraDevice(cameraId); 730 if (res) { 731 return res; 732 } 733 } 734 735 if (cameraId != mCameraId) { 736 return BAD_INDEX; 737 } 738 739 const char *flashMode = 740 mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); 741 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { 742 *hasFlash = true; 743 } else { 744 *hasFlash = false; 745 } 746 747 return OK; 748} 749 750status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { 751 status_t res = OK; 752 res = mDevice->startPreview(); 753 if (res) { 754 ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, 755 strerror(-res), res); 756 return res; 757 } 758 759 mParameters.set(CameraParameters::KEY_FLASH_MODE, 760 CameraParameters::FLASH_MODE_TORCH); 761 762 return mDevice->setParameters(mParameters); 763} 764 765status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( 766 int32_t *width, int32_t *height) { 767 if (!width || !height) { 768 return BAD_VALUE; 769 } 770 771 int32_t w = INT32_MAX; 772 int32_t h = 1; 773 Vector<Size> sizes; 774 775 mParameters.getSupportedPreviewSizes(sizes); 776 for (size_t i = 0; i < sizes.size(); i++) { 777 Size s = sizes[i]; 778 if (w * h > s.width * s.height) { 779 w = s.width; 780 h = s.height; 781 } 782 } 783 784 if (w == INT32_MAX) { 785 return NAME_NOT_FOUND; 786 } 787 788 *width = w; 789 *height = h; 790 791 return OK; 792} 793 794status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( 795 sp<CameraHardwareInterface> device, int32_t width, int32_t height) { 796 status_t res; 797 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 798 799 mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 800 true, true); 801 if (mSurfaceTexture == NULL) { 802 return NO_MEMORY; 803 } 804 805 int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 806 res = mSurfaceTexture->setDefaultBufferSize(width, height); 807 if (res) { 808 return res; 809 } 810 res = mSurfaceTexture->setDefaultBufferFormat(format); 811 if (res) { 812 return res; 813 } 814 815 mAnw = new Surface(mProducer, /*useAsync*/ true); 816 if (mAnw == NULL) { 817 return NO_MEMORY; 818 } 819 820 res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 821 if (res) { 822 ALOGE("%s: Unable to connect to native window", __FUNCTION__); 823 return res; 824 } 825 826 return device->setPreviewWindow(mAnw); 827} 828 829status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( 830 const String8& cameraId) { 831 sp<CameraHardwareInterface> device = 832 new CameraHardwareInterface(cameraId.string()); 833 834 status_t res = device->initialize(mCameraModule); 835 if (res) { 836 ALOGE("%s: initializing camera %s failed", __FUNCTION__, 837 cameraId.string()); 838 return res; 839 } 840 841 // need to set __get_memory in set_callbacks(). 842 device->setCallbacks(NULL, NULL, NULL, NULL); 843 844 mParameters = device->getParameters(); 845 846 int32_t width, height; 847 res = getSmallestSurfaceSize(&width, &height); 848 if (res) { 849 ALOGE("%s: failed to get smallest surface size for camera %s", 850 __FUNCTION__, cameraId.string()); 851 return res; 852 } 853 854 res = initializePreviewWindow(device, width, height); 855 if (res) { 856 ALOGE("%s: failed to initialize preview window for camera %s", 857 __FUNCTION__, cameraId.string()); 858 return res; 859 } 860 861 mCameraId = cameraId; 862 mDevice = device; 863 return OK; 864} 865 866status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { 867 if (mDevice == NULL) { 868 return OK; 869 } 870 871 mParameters.set(CameraParameters::KEY_FLASH_MODE, 872 CameraParameters::FLASH_MODE_OFF); 873 mDevice->setParameters(mParameters); 874 mDevice->stopPreview(); 875 status_t res = native_window_api_disconnect(mAnw.get(), 876 NATIVE_WINDOW_API_CAMERA); 877 if (res) { 878 ALOGW("%s: native_window_api_disconnect failed: %s (%d)", 879 __FUNCTION__, strerror(-res), res); 880 } 881 mDevice->setPreviewWindow(NULL); 882 mDevice->release(); 883 884 return OK; 885} 886// CameraHardwareInterfaceFlashControl implementation ends 887 888} 889