Home | History | Annotate | Download | only in libcameraservice
      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 "device3/Camera3Device.h"
     31 
     32 
     33 namespace android {
     34 
     35 /////////////////////////////////////////////////////////////////////
     36 // CameraFlashlight implementation begins
     37 // used by camera service to control flashflight.
     38 /////////////////////////////////////////////////////////////////////
     39 CameraFlashlight::CameraFlashlight(CameraModule& cameraModule,
     40         const camera_module_callbacks_t& callbacks) :
     41         mCameraModule(&cameraModule),
     42         mCallbacks(&callbacks),
     43         mFlashlightMapInitialized(false) {
     44 }
     45 
     46 CameraFlashlight::~CameraFlashlight() {
     47 }
     48 
     49 status_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->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
     59         mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks);
     60         if (mFlashControl == NULL) {
     61             ALOGV("%s: cannot create flash control for module api v2.4+",
     62                      __FUNCTION__);
     63             return NO_MEMORY;
     64         }
     65     } else {
     66         uint32_t deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
     67 
     68         if (mCameraModule->getModuleApiVersion() >=
     69                     CAMERA_MODULE_API_VERSION_2_0) {
     70             camera_info info;
     71             res = mCameraModule->getCameraInfo(
     72                     atoi(String8(cameraId).string()), &info);
     73             if (res) {
     74                 ALOGE("%s: failed to get camera info for camera %s",
     75                         __FUNCTION__, cameraId.string());
     76                 return res;
     77             }
     78             deviceVersion = info.device_version;
     79         }
     80 
     81         if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_0) {
     82             CameraDeviceClientFlashControl *flashControl =
     83                     new CameraDeviceClientFlashControl(*mCameraModule,
     84                                                        *mCallbacks);
     85             if (!flashControl) {
     86                 return NO_MEMORY;
     87             }
     88 
     89             mFlashControl = flashControl;
     90         } else {
     91             mFlashControl =
     92                     new CameraHardwareInterfaceFlashControl(*mCameraModule,
     93                                                             *mCallbacks);
     94         }
     95     }
     96 
     97     return OK;
     98 }
     99 
    100 status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
    101     if (!mFlashlightMapInitialized) {
    102         ALOGE("%s: findFlashUnits() must be called before this method.",
    103                __FUNCTION__);
    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 
    157 status_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 
    195 bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
    196     Mutex::Autolock l(mLock);
    197     return hasFlashUnitLocked(cameraId);
    198 }
    199 
    200 bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
    201     if (!mFlashlightMapInitialized) {
    202         ALOGE("%s: findFlashUnits() must be called before this method.",
    203                __FUNCTION__);
    204         return false;
    205     }
    206 
    207     ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
    208     if (index == NAME_NOT_FOUND) {
    209         ALOGE("%s: camera %s not present when findFlashUnits() was called",
    210                 __FUNCTION__, cameraId.string());
    211         return false;
    212     }
    213 
    214     return mHasFlashlightMap.valueAt(index);
    215 }
    216 
    217 status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
    218     ALOGV("%s: prepare for device open", __FUNCTION__);
    219 
    220     Mutex::Autolock l(mLock);
    221     if (!mFlashlightMapInitialized) {
    222         ALOGE("%s: findFlashUnits() must be called before this method.",
    223                __FUNCTION__);
    224         return NO_INIT;
    225     }
    226 
    227     if (mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) {
    228         // framework is going to open a camera device, all flash light control
    229         // should be closed for backward compatible support.
    230         mFlashControl.clear();
    231 
    232         if (mOpenedCameraIds.size() == 0) {
    233             // notify torch unavailable for all cameras with a flash
    234             int numCameras = mCameraModule->getNumberOfCameras();
    235             for (int i = 0; i < numCameras; i++) {
    236                 if (hasFlashUnitLocked(String8::format("%d", i))) {
    237                     mCallbacks->torch_mode_status_change(mCallbacks,
    238                             String8::format("%d", i).string(),
    239                             TORCH_MODE_STATUS_NOT_AVAILABLE);
    240                 }
    241             }
    242         }
    243 
    244         // close flash control that may be opened by calling hasFlashUnitLocked.
    245         mFlashControl.clear();
    246     }
    247 
    248     if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
    249         mOpenedCameraIds.add(cameraId);
    250     }
    251 
    252     return OK;
    253 }
    254 
    255 status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
    256     ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
    257 
    258     Mutex::Autolock l(mLock);
    259     if (!mFlashlightMapInitialized) {
    260         ALOGE("%s: findFlashUnits() must be called before this method.",
    261                __FUNCTION__);
    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->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) {
    278         // notify torch available for all cameras with a flash
    279         int numCameras = mCameraModule->getNumberOfCameras();
    280         for (int i = 0; i < numCameras; i++) {
    281             if (hasFlashUnitLocked(String8::format("%d", i))) {
    282                 mCallbacks->torch_mode_status_change(mCallbacks,
    283                         String8::format("%d", i).string(),
    284                         TORCH_MODE_STATUS_AVAILABLE_OFF);
    285             }
    286         }
    287     }
    288 
    289     return OK;
    290 }
    291 // CameraFlashlight implementation ends
    292 
    293 
    294 FlashControlBase::~FlashControlBase() {
    295 }
    296 
    297 /////////////////////////////////////////////////////////////////////
    298 // ModuleFlashControl implementation begins
    299 // Flash control for camera module v2.4 and above.
    300 /////////////////////////////////////////////////////////////////////
    301 ModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule,
    302         const camera_module_callbacks_t& callbacks) :
    303         mCameraModule(&cameraModule) {
    304     (void) callbacks;
    305 }
    306 
    307 ModuleFlashControl::~ModuleFlashControl() {
    308 }
    309 
    310 status_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 
    336 status_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 /////////////////////////////////////////////////////////////////////
    349 CameraDeviceClientFlashControl::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 
    359 CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() {
    360     disconnectCameraDevice();
    361     if (mMetadata) {
    362         delete mMetadata;
    363     }
    364 
    365     mSurface.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 
    380 status_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     mSurface = new Surface(mProducer, /*useAsync*/ true);
    402     if (mSurface == NULL) {
    403         return NO_MEMORY;
    404     }
    405     res = device->createStream(mSurface, width, height, format,
    406             HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mStreamId);
    407     if (res) {
    408         return res;
    409     }
    410 
    411     res = device->configureStreams();
    412     if (res) {
    413         return res;
    414     }
    415 
    416     return res;
    417 }
    418 
    419 status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize(
    420         const camera_info& info, int32_t *width, int32_t *height) {
    421     if (!width || !height) {
    422         return BAD_VALUE;
    423     }
    424 
    425     int32_t w = INT32_MAX;
    426     int32_t h = 1;
    427 
    428     CameraMetadata metadata;
    429     metadata = info.static_camera_characteristics;
    430     camera_metadata_entry streamConfigs =
    431             metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
    432     for (size_t i = 0; i < streamConfigs.count; i += 4) {
    433         int32_t fmt = streamConfigs.data.i32[i];
    434         if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) {
    435             int32_t ww = streamConfigs.data.i32[i + 1];
    436             int32_t hh = streamConfigs.data.i32[i + 2];
    437 
    438             if (w * h > ww * hh) {
    439                 w = ww;
    440                 h = hh;
    441             }
    442         }
    443     }
    444 
    445     // if stream configuration is not found, try available processed sizes.
    446     if (streamConfigs.count == 0) {
    447         camera_metadata_entry availableProcessedSizes =
    448             metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
    449         for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
    450             int32_t ww = availableProcessedSizes.data.i32[i];
    451             int32_t hh = availableProcessedSizes.data.i32[i + 1];
    452             if (w * h > ww * hh) {
    453                 w = ww;
    454                 h = hh;
    455             }
    456         }
    457     }
    458 
    459     if (w == INT32_MAX) {
    460         return NAME_NOT_FOUND;
    461     }
    462 
    463     *width = w;
    464     *height = h;
    465 
    466     return OK;
    467 }
    468 
    469 status_t CameraDeviceClientFlashControl::connectCameraDevice(
    470         const String8& cameraId) {
    471     camera_info info;
    472     status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info);
    473     if (res != 0) {
    474         ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
    475                 cameraId.string());
    476         return res;
    477     }
    478 
    479     sp<CameraDeviceBase> device =
    480             new Camera3Device(atoi(cameraId.string()));
    481     if (device == NULL) {
    482         return NO_MEMORY;
    483     }
    484 
    485     res = device->initialize(mCameraModule);
    486     if (res) {
    487         return res;
    488     }
    489 
    490     int32_t width, height;
    491     res = getSmallestSurfaceSize(info, &width, &height);
    492     if (res) {
    493         return res;
    494     }
    495     res = initializeSurface(device, width, height);
    496     if (res) {
    497         return res;
    498     }
    499 
    500     mCameraId = cameraId;
    501     mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1);
    502     mDevice = device;
    503 
    504     return OK;
    505 }
    506 
    507 status_t CameraDeviceClientFlashControl::disconnectCameraDevice() {
    508     if (mDevice != NULL) {
    509         mDevice->disconnect();
    510         mDevice.clear();
    511     }
    512 
    513     return OK;
    514 }
    515 
    516 
    517 
    518 status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId,
    519         bool *hasFlash) {
    520     ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__,
    521             cameraId.string());
    522 
    523     Mutex::Autolock l(mLock);
    524     return hasFlashUnitLocked(cameraId, hasFlash);
    525 
    526 }
    527 
    528 status_t CameraDeviceClientFlashControl::hasFlashUnitLocked(
    529         const String8& cameraId, bool *hasFlash) {
    530     if (!hasFlash) {
    531         return BAD_VALUE;
    532     }
    533 
    534     camera_info info;
    535     status_t res = mCameraModule->getCameraInfo(
    536             atoi(cameraId.string()), &info);
    537     if (res != 0) {
    538         ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__,
    539                 cameraId.string());
    540         return res;
    541     }
    542 
    543     CameraMetadata metadata;
    544     metadata = info.static_camera_characteristics;
    545     camera_metadata_entry flashAvailable =
    546             metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
    547     if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) {
    548         *hasFlash = true;
    549     }
    550 
    551     return OK;
    552 }
    553 
    554 status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() {
    555     status_t res;
    556 
    557     if (mMetadata == NULL) {
    558         mMetadata = new CameraMetadata();
    559         if (mMetadata == NULL) {
    560             return NO_MEMORY;
    561         }
    562         res = mDevice->createDefaultRequest(
    563                 CAMERA3_TEMPLATE_PREVIEW, mMetadata);
    564         if (res) {
    565             return res;
    566         }
    567     }
    568 
    569     uint8_t torchOn = ANDROID_FLASH_MODE_TORCH;
    570     mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1);
    571     mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1);
    572 
    573     uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
    574     mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
    575 
    576     int32_t requestId = 0;
    577     mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1);
    578 
    579     if (mStreaming) {
    580         res = mDevice->setStreamingRequest(*mMetadata);
    581     } else {
    582         res = mDevice->capture(*mMetadata);
    583     }
    584     return res;
    585 }
    586 
    587 
    588 
    589 
    590 status_t CameraDeviceClientFlashControl::setTorchMode(
    591         const String8& cameraId, bool enabled) {
    592     bool hasFlash = false;
    593 
    594     Mutex::Autolock l(mLock);
    595     status_t res = hasFlashUnitLocked(cameraId, &hasFlash);
    596 
    597     // pre-check
    598     if (enabled) {
    599         // invalid camera?
    600         if (res) {
    601             return -EINVAL;
    602         }
    603         // no flash unit?
    604         if (!hasFlash) {
    605             return -ENOSYS;
    606         }
    607         // already opened for a different device?
    608         if (mDevice != NULL && cameraId != mCameraId) {
    609             return BAD_INDEX;
    610         }
    611     } else if (mDevice == NULL || cameraId != mCameraId) {
    612         // disabling the torch mode of an un-opened or different device.
    613         return OK;
    614     } else {
    615         // disabling the torch mode of currently opened device
    616         disconnectCameraDevice();
    617         mTorchEnabled = false;
    618         mCallbacks->torch_mode_status_change(mCallbacks,
    619             cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
    620         return OK;
    621     }
    622 
    623     if (mDevice == NULL) {
    624         res = connectCameraDevice(cameraId);
    625         if (res) {
    626             return res;
    627         }
    628     }
    629 
    630     res = submitTorchEnabledRequest();
    631     if (res) {
    632         return res;
    633     }
    634 
    635     mTorchEnabled = true;
    636     mCallbacks->torch_mode_status_change(mCallbacks,
    637             cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
    638     return OK;
    639 }
    640 // CameraDeviceClientFlashControl implementation ends
    641 
    642 
    643 /////////////////////////////////////////////////////////////////////
    644 // CameraHardwareInterfaceFlashControl implementation begins
    645 // Flash control for camera module <= v2.3 and camera HAL v1
    646 /////////////////////////////////////////////////////////////////////
    647 CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
    648         CameraModule& cameraModule,
    649         const camera_module_callbacks_t& callbacks) :
    650         mCameraModule(&cameraModule),
    651         mCallbacks(&callbacks),
    652         mTorchEnabled(false) {
    653 
    654 }
    655 
    656 CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
    657     disconnectCameraDevice();
    658 
    659     mSurface.clear();
    660     mSurfaceTexture.clear();
    661     mProducer.clear();
    662     mConsumer.clear();
    663 
    664     if (mTorchEnabled) {
    665         if (mCallbacks) {
    666             ALOGV("%s: notify the framework that torch was turned off",
    667                     __FUNCTION__);
    668             mCallbacks->torch_mode_status_change(mCallbacks,
    669                     mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
    670         }
    671     }
    672 }
    673 
    674 status_t CameraHardwareInterfaceFlashControl::setTorchMode(
    675         const String8& cameraId, bool enabled) {
    676     Mutex::Autolock l(mLock);
    677 
    678     // pre-check
    679     status_t res;
    680     if (enabled) {
    681         bool hasFlash = false;
    682         // Check if it has a flash unit and leave camera device open.
    683         res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
    684         // invalid camera?
    685         if (res) {
    686             // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
    687             // another camera device.
    688             return res == BAD_INDEX ? BAD_INDEX : -EINVAL;
    689         }
    690         // no flash unit?
    691         if (!hasFlash) {
    692             // Disconnect camera device if it has no flash.
    693             disconnectCameraDevice();
    694             return -ENOSYS;
    695         }
    696     } else if (mDevice == NULL || cameraId != mCameraId) {
    697         // disabling the torch mode of an un-opened or different device.
    698         return OK;
    699     } else {
    700         // disabling the torch mode of currently opened device
    701         disconnectCameraDevice();
    702         mTorchEnabled = false;
    703         mCallbacks->torch_mode_status_change(mCallbacks,
    704             cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
    705         return OK;
    706     }
    707 
    708     res = startPreviewAndTorch();
    709     if (res) {
    710         return res;
    711     }
    712 
    713     mTorchEnabled = true;
    714     mCallbacks->torch_mode_status_change(mCallbacks,
    715             cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
    716     return OK;
    717 }
    718 
    719 status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
    720         const String8& cameraId, bool *hasFlash) {
    721     Mutex::Autolock l(mLock);
    722     // Close device after checking if it has a flash unit.
    723     return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
    724 }
    725 
    726 status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
    727         const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
    728     bool closeCameraDevice = false;
    729 
    730     if (!hasFlash) {
    731         return BAD_VALUE;
    732     }
    733 
    734     status_t res;
    735     if (mDevice == NULL) {
    736         // Connect to camera device to query if it has a flash unit.
    737         res = connectCameraDevice(cameraId);
    738         if (res) {
    739             return res;
    740         }
    741         // Close camera device only when it is just opened and the caller doesn't want to keep
    742         // the camera device open.
    743         closeCameraDevice = !keepDeviceOpen;
    744     }
    745 
    746     if (cameraId != mCameraId) {
    747         return BAD_INDEX;
    748     }
    749 
    750     const char *flashMode =
    751             mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
    752     if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
    753         *hasFlash = true;
    754     } else {
    755         *hasFlash = false;
    756     }
    757 
    758     if (closeCameraDevice) {
    759         res = disconnectCameraDevice();
    760         if (res != OK) {
    761             ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
    762                     strerror(-res), res);
    763             return res;
    764         }
    765     }
    766 
    767     return OK;
    768 }
    769 
    770 status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() {
    771     status_t res = OK;
    772     res = mDevice->startPreview();
    773     if (res) {
    774         ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__,
    775                 strerror(-res), res);
    776         return res;
    777     }
    778 
    779     mParameters.set(CameraParameters::KEY_FLASH_MODE,
    780             CameraParameters::FLASH_MODE_TORCH);
    781 
    782     return mDevice->setParameters(mParameters);
    783 }
    784 
    785 status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize(
    786         int32_t *width, int32_t *height) {
    787     if (!width || !height) {
    788         return BAD_VALUE;
    789     }
    790 
    791     int32_t w = INT32_MAX;
    792     int32_t h = 1;
    793     Vector<Size> sizes;
    794 
    795     mParameters.getSupportedPreviewSizes(sizes);
    796     for (size_t i = 0; i < sizes.size(); i++) {
    797         Size s = sizes[i];
    798         if (w * h > s.width * s.height) {
    799             w = s.width;
    800             h = s.height;
    801         }
    802     }
    803 
    804     if (w == INT32_MAX) {
    805         return NAME_NOT_FOUND;
    806     }
    807 
    808     *width = w;
    809     *height = h;
    810 
    811     return OK;
    812 }
    813 
    814 status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
    815         sp<CameraHardwareInterface> device, int32_t width, int32_t height) {
    816     status_t res;
    817     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
    818 
    819     mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL,
    820             true, true);
    821     if (mSurfaceTexture == NULL) {
    822         return NO_MEMORY;
    823     }
    824 
    825     int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    826     res = mSurfaceTexture->setDefaultBufferSize(width, height);
    827     if (res) {
    828         return res;
    829     }
    830     res = mSurfaceTexture->setDefaultBufferFormat(format);
    831     if (res) {
    832         return res;
    833     }
    834 
    835     mSurface = new Surface(mProducer, /*useAsync*/ true);
    836     if (mSurface == NULL) {
    837         return NO_MEMORY;
    838     }
    839 
    840     res = native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_CAMERA);
    841     if (res) {
    842         ALOGE("%s: Unable to connect to native window", __FUNCTION__);
    843         return res;
    844     }
    845 
    846     return device->setPreviewWindow(mSurface);
    847 }
    848 
    849 status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
    850         const String8& cameraId) {
    851     sp<CameraHardwareInterface> device =
    852             new CameraHardwareInterface(cameraId.string());
    853 
    854     status_t res = device->initialize(mCameraModule);
    855     if (res) {
    856         ALOGE("%s: initializing camera %s failed", __FUNCTION__,
    857                 cameraId.string());
    858         return res;
    859     }
    860 
    861     // need to set __get_memory in set_callbacks().
    862     device->setCallbacks(NULL, NULL, NULL, NULL);
    863 
    864     mParameters = device->getParameters();
    865 
    866     int32_t width, height;
    867     res = getSmallestSurfaceSize(&width, &height);
    868     if (res) {
    869         ALOGE("%s: failed to get smallest surface size for camera %s",
    870                 __FUNCTION__, cameraId.string());
    871         return res;
    872     }
    873 
    874     res = initializePreviewWindow(device, width, height);
    875     if (res) {
    876         ALOGE("%s: failed to initialize preview window for camera %s",
    877                 __FUNCTION__, cameraId.string());
    878         return res;
    879     }
    880 
    881     mCameraId = cameraId;
    882     mDevice = device;
    883     return OK;
    884 }
    885 
    886 status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() {
    887     if (mDevice == NULL) {
    888         return OK;
    889     }
    890 
    891     if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
    892         // There is a flash, turn if off.
    893         // (If there isn't one, leave the parameter null)
    894         mParameters.set(CameraParameters::KEY_FLASH_MODE,
    895                 CameraParameters::FLASH_MODE_OFF);
    896         mDevice->setParameters(mParameters);
    897     }
    898     mDevice->stopPreview();
    899     status_t res = native_window_api_disconnect(mSurface.get(),
    900             NATIVE_WINDOW_API_CAMERA);
    901     if (res) {
    902         ALOGW("%s: native_window_api_disconnect failed: %s (%d)",
    903                 __FUNCTION__, strerror(-res), res);
    904     }
    905     mDevice->setPreviewWindow(NULL);
    906     mDevice->release();
    907     mDevice = NULL;
    908 
    909     return OK;
    910 }
    911 // CameraHardwareInterfaceFlashControl implementation ends
    912 
    913 }
    914