CameraFlashlight.cpp revision b97babb8c08969b55af3b6456d15f764c8873d3f
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, 392 HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mStreamId); 393 if (res) { 394 return res; 395 } 396 397 res = device->configureStreams(); 398 if (res) { 399 return res; 400 } 401 402 return res; 403} 404 405status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( 406 const camera_info& info, int32_t *width, int32_t *height) { 407 if (!width || !height) { 408 return BAD_VALUE; 409 } 410 411 int32_t w = INT32_MAX; 412 int32_t h = 1; 413 414 CameraMetadata metadata; 415 metadata = info.static_camera_characteristics; 416 camera_metadata_entry streamConfigs = 417 metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); 418 for (size_t i = 0; i < streamConfigs.count; i += 4) { 419 int32_t fmt = streamConfigs.data.i32[i]; 420 if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) { 421 int32_t ww = streamConfigs.data.i32[i + 1]; 422 int32_t hh = streamConfigs.data.i32[i + 2]; 423 424 if (w * h > ww * hh) { 425 w = ww; 426 h = hh; 427 } 428 } 429 } 430 431 // if stream configuration is not found, try available processed sizes. 432 if (streamConfigs.count == 0) { 433 camera_metadata_entry availableProcessedSizes = 434 metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES); 435 for (size_t i = 0; i < availableProcessedSizes.count; i += 2) { 436 int32_t ww = availableProcessedSizes.data.i32[i]; 437 int32_t hh = availableProcessedSizes.data.i32[i + 1]; 438 if (w * h > ww * hh) { 439 w = ww; 440 h = hh; 441 } 442 } 443 } 444 445 if (w == INT32_MAX) { 446 return NAME_NOT_FOUND; 447 } 448 449 *width = w; 450 *height = h; 451 452 return OK; 453} 454 455status_t CameraDeviceClientFlashControl::connectCameraDevice( 456 const String8& cameraId) { 457 camera_info info; 458 status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); 459 if (res != 0) { 460 ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 461 cameraId.string()); 462 return res; 463 } 464 465 sp<CameraDeviceBase> device = 466 CameraDeviceFactory::createDevice(atoi(cameraId.string())); 467 if (device == NULL) { 468 return NO_MEMORY; 469 } 470 471 res = device->initialize(mCameraModule); 472 if (res) { 473 return res; 474 } 475 476 int32_t width, height; 477 res = getSmallestSurfaceSize(info, &width, &height); 478 if (res) { 479 return res; 480 } 481 res = initializeSurface(device, width, height); 482 if (res) { 483 return res; 484 } 485 486 mCameraId = cameraId; 487 mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1); 488 mDevice = device; 489 490 return OK; 491} 492 493status_t CameraDeviceClientFlashControl::disconnectCameraDevice() { 494 if (mDevice != NULL) { 495 mDevice->disconnect(); 496 mDevice.clear(); 497 } 498 499 return OK; 500} 501 502 503 504status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId, 505 bool *hasFlash) { 506 ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, 507 cameraId.string()); 508 509 Mutex::Autolock l(mLock); 510 return hasFlashUnitLocked(cameraId, hasFlash); 511 512} 513 514status_t CameraDeviceClientFlashControl::hasFlashUnitLocked( 515 const String8& cameraId, bool *hasFlash) { 516 if (!hasFlash) { 517 return BAD_VALUE; 518 } 519 520 camera_info info; 521 status_t res = mCameraModule->getCameraInfo( 522 atoi(cameraId.string()), &info); 523 if (res != 0) { 524 ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 525 cameraId.string()); 526 return res; 527 } 528 529 CameraMetadata metadata; 530 metadata = info.static_camera_characteristics; 531 camera_metadata_entry flashAvailable = 532 metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 533 if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 534 *hasFlash = true; 535 } 536 537 return OK; 538} 539 540status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() { 541 status_t res; 542 543 if (mMetadata == NULL) { 544 mMetadata = new CameraMetadata(); 545 if (mMetadata == NULL) { 546 return NO_MEMORY; 547 } 548 res = mDevice->createDefaultRequest( 549 CAMERA3_TEMPLATE_PREVIEW, mMetadata); 550 if (res) { 551 return res; 552 } 553 } 554 555 uint8_t torchOn = ANDROID_FLASH_MODE_TORCH; 556 mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); 557 mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); 558 559 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; 560 mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); 561 562 int32_t requestId = 0; 563 mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); 564 565 if (mStreaming) { 566 res = mDevice->setStreamingRequest(*mMetadata); 567 } else { 568 res = mDevice->capture(*mMetadata); 569 } 570 return res; 571} 572 573 574 575 576status_t CameraDeviceClientFlashControl::setTorchMode( 577 const String8& cameraId, bool enabled) { 578 bool hasFlash = false; 579 580 Mutex::Autolock l(mLock); 581 status_t res = hasFlashUnitLocked(cameraId, &hasFlash); 582 583 // pre-check 584 if (enabled) { 585 // invalid camera? 586 if (res) { 587 return -EINVAL; 588 } 589 // no flash unit? 590 if (!hasFlash) { 591 return -ENOSYS; 592 } 593 // already opened for a different device? 594 if (mDevice != NULL && cameraId != mCameraId) { 595 return BAD_INDEX; 596 } 597 } else if (mDevice == NULL || cameraId != mCameraId) { 598 // disabling the torch mode of an un-opened or different device. 599 return OK; 600 } else { 601 // disabling the torch mode of currently opened device 602 disconnectCameraDevice(); 603 mTorchEnabled = false; 604 mCallbacks->torch_mode_status_change(mCallbacks, 605 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 606 return OK; 607 } 608 609 if (mDevice == NULL) { 610 res = connectCameraDevice(cameraId); 611 if (res) { 612 return res; 613 } 614 } 615 616 res = submitTorchEnabledRequest(); 617 if (res) { 618 return res; 619 } 620 621 mTorchEnabled = true; 622 mCallbacks->torch_mode_status_change(mCallbacks, 623 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 624 return OK; 625} 626// CameraDeviceClientFlashControl implementation ends 627 628 629///////////////////////////////////////////////////////////////////// 630// CameraHardwareInterfaceFlashControl implementation begins 631// Flash control for camera module <= v2.3 and camera HAL v1 632///////////////////////////////////////////////////////////////////// 633CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( 634 CameraModule& cameraModule, 635 const camera_module_callbacks_t& callbacks) : 636 mCameraModule(&cameraModule), 637 mCallbacks(&callbacks), 638 mTorchEnabled(false) { 639 640} 641 642CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { 643 disconnectCameraDevice(); 644 645 mAnw.clear(); 646 mSurfaceTexture.clear(); 647 mProducer.clear(); 648 mConsumer.clear(); 649 650 if (mTorchEnabled) { 651 if (mCallbacks) { 652 ALOGV("%s: notify the framework that torch was turned off", 653 __FUNCTION__); 654 mCallbacks->torch_mode_status_change(mCallbacks, 655 mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 656 } 657 } 658} 659 660status_t CameraHardwareInterfaceFlashControl::setTorchMode( 661 const String8& cameraId, bool enabled) { 662 Mutex::Autolock l(mLock); 663 664 // pre-check 665 status_t res; 666 if (enabled) { 667 bool hasFlash = false; 668 res = hasFlashUnitLocked(cameraId, &hasFlash); 669 // invalid camera? 670 if (res) { 671 // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to 672 // another camera device. 673 return res == BAD_INDEX ? BAD_INDEX : -EINVAL; 674 } 675 // no flash unit? 676 if (!hasFlash) { 677 return -ENOSYS; 678 } 679 } else if (mDevice == NULL || cameraId != mCameraId) { 680 // disabling the torch mode of an un-opened or different device. 681 return OK; 682 } else { 683 // disabling the torch mode of currently opened device 684 disconnectCameraDevice(); 685 mTorchEnabled = false; 686 mCallbacks->torch_mode_status_change(mCallbacks, 687 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 688 return OK; 689 } 690 691 res = startPreviewAndTorch(); 692 if (res) { 693 return res; 694 } 695 696 mTorchEnabled = true; 697 mCallbacks->torch_mode_status_change(mCallbacks, 698 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 699 return OK; 700} 701 702status_t CameraHardwareInterfaceFlashControl::hasFlashUnit( 703 const String8& cameraId, bool *hasFlash) { 704 Mutex::Autolock l(mLock); 705 return hasFlashUnitLocked(cameraId, hasFlash); 706} 707 708status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( 709 const String8& cameraId, bool *hasFlash) { 710 if (!hasFlash) { 711 return BAD_VALUE; 712 } 713 714 status_t res; 715 if (mDevice == NULL) { 716 res = connectCameraDevice(cameraId); 717 if (res) { 718 return res; 719 } 720 } 721 722 if (cameraId != mCameraId) { 723 return BAD_INDEX; 724 } 725 726 const char *flashMode = 727 mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); 728 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { 729 *hasFlash = true; 730 } else { 731 *hasFlash = false; 732 } 733 734 return OK; 735} 736 737status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { 738 status_t res = OK; 739 res = mDevice->startPreview(); 740 if (res) { 741 ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, 742 strerror(-res), res); 743 return res; 744 } 745 746 mParameters.set(CameraParameters::KEY_FLASH_MODE, 747 CameraParameters::FLASH_MODE_TORCH); 748 749 return mDevice->setParameters(mParameters); 750} 751 752status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( 753 int32_t *width, int32_t *height) { 754 if (!width || !height) { 755 return BAD_VALUE; 756 } 757 758 int32_t w = INT32_MAX; 759 int32_t h = 1; 760 Vector<Size> sizes; 761 762 mParameters.getSupportedPreviewSizes(sizes); 763 for (size_t i = 0; i < sizes.size(); i++) { 764 Size s = sizes[i]; 765 if (w * h > s.width * s.height) { 766 w = s.width; 767 h = s.height; 768 } 769 } 770 771 if (w == INT32_MAX) { 772 return NAME_NOT_FOUND; 773 } 774 775 *width = w; 776 *height = h; 777 778 return OK; 779} 780 781status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( 782 sp<CameraHardwareInterface> device, int32_t width, int32_t height) { 783 status_t res; 784 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 785 786 mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 787 true, true); 788 if (mSurfaceTexture == NULL) { 789 return NO_MEMORY; 790 } 791 792 int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 793 res = mSurfaceTexture->setDefaultBufferSize(width, height); 794 if (res) { 795 return res; 796 } 797 res = mSurfaceTexture->setDefaultBufferFormat(format); 798 if (res) { 799 return res; 800 } 801 802 mAnw = new Surface(mProducer, /*useAsync*/ true); 803 if (mAnw == NULL) { 804 return NO_MEMORY; 805 } 806 807 res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 808 if (res) { 809 ALOGE("%s: Unable to connect to native window", __FUNCTION__); 810 return res; 811 } 812 813 return device->setPreviewWindow(mAnw); 814} 815 816status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( 817 const String8& cameraId) { 818 sp<CameraHardwareInterface> device = 819 new CameraHardwareInterface(cameraId.string()); 820 821 status_t res = device->initialize(mCameraModule); 822 if (res) { 823 ALOGE("%s: initializing camera %s failed", __FUNCTION__, 824 cameraId.string()); 825 return res; 826 } 827 828 // need to set __get_memory in set_callbacks(). 829 device->setCallbacks(NULL, NULL, NULL, NULL); 830 831 mParameters = device->getParameters(); 832 833 int32_t width, height; 834 res = getSmallestSurfaceSize(&width, &height); 835 if (res) { 836 ALOGE("%s: failed to get smallest surface size for camera %s", 837 __FUNCTION__, cameraId.string()); 838 return res; 839 } 840 841 res = initializePreviewWindow(device, width, height); 842 if (res) { 843 ALOGE("%s: failed to initialize preview window for camera %s", 844 __FUNCTION__, cameraId.string()); 845 return res; 846 } 847 848 mCameraId = cameraId; 849 mDevice = device; 850 return OK; 851} 852 853status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { 854 if (mDevice == NULL) { 855 return OK; 856 } 857 858 mParameters.set(CameraParameters::KEY_FLASH_MODE, 859 CameraParameters::FLASH_MODE_OFF); 860 mDevice->setParameters(mParameters); 861 mDevice->stopPreview(); 862 status_t res = native_window_api_disconnect(mAnw.get(), 863 NATIVE_WINDOW_API_CAMERA); 864 if (res) { 865 ALOGW("%s: native_window_api_disconnect failed: %s (%d)", 866 __FUNCTION__, strerror(-res), res); 867 } 868 mDevice->setPreviewWindow(NULL); 869 mDevice->release(); 870 871 return OK; 872} 873// CameraHardwareInterfaceFlashControl implementation ends 874 875} 876