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