13068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen/* 23068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * Copyright (C) 2015 The Android Open Source Project 33068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * 43068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * Licensed under the Apache License, Version 2.0 (the "License"); 53068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * you may not use this file except in compliance with the License. 63068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * You may obtain a copy of the License at 73068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * 83068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * http://www.apache.org/licenses/LICENSE-2.0 93068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * 103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * Unless required by applicable law or agreed to in writing, software 113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * distributed under the License is distributed on an "AS IS" BASIS, 123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * See the License for the specific language governing permissions and 143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen * limitations under the License. 153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen */ 163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#define LOG_TAG "CameraFlashlight" 183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#define ATRACE_TAG ATRACE_TAG_CAMERA 1988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// #define LOG_NDEBUG 0 203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include <utils/Log.h> 223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include <utils/Trace.h> 233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include <cutils/properties.h> 243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "camera/CameraMetadata.h" 263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "CameraFlashlight.h" 273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "gui/IGraphicBufferConsumer.h" 283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "gui/BufferQueue.h" 293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "camera/camera2/CaptureRequest.h" 303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen#include "CameraDeviceFactory.h" 313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chennamespace android { 343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 3688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraFlashlight implementation begins 3788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// used by camera service to control flashflight. 3888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraFlashlight::CameraFlashlight(CameraModule& cameraModule, 403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_module_callbacks_t& callbacks) : 413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraModule(&cameraModule), 4288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks(&callbacks), 4388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashlightMapInitialized(false) { 443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraFlashlight::~CameraFlashlight() { 473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { 503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__, 513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string()); 523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mFlashControl != NULL) { 533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return INVALID_OPERATION; 543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = OK; 573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 58676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) { 5988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks); 603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mFlashControl == NULL) { 613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: cannot create flash control for module api v2.4+", 623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen __FUNCTION__); 633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } else { 663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen uint32_t deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; 673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 68676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() >= 69676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen CAMERA_MODULE_API_VERSION_2_0) { 703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mCameraModule->getCameraInfo( 723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen atoi(String8(cameraId).string()), &info); 733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 7488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: failed to get camera info for camera %s", 753068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen __FUNCTION__, cameraId.string()); 763068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen deviceVersion = info.device_version; 793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 803068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 813068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) { 823068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraDeviceClientFlashControl *flashControl = 833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen new CameraDeviceClientFlashControl(*mCameraModule, 843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *mCallbacks); 853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!flashControl) { 863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mFlashControl = flashControl; 9088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 91d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mFlashControl = 92d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen new CameraHardwareInterfaceFlashControl(*mCameraModule, 93d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *mCallbacks); 943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 10088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) { 10188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 10232ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 10332ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 1043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_INIT; 1053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 1073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__, 1083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string(), enabled); 1093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 1103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = OK; 1113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 1123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 113cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) { 114cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // This case is needed to avoid state corruption during the following call sequence: 115cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // CameraService::setTorchMode for camera ID 0 begins, does torch status checks 116cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // CameraService::connect for camera ID 0 begins, calls prepareDeviceOpen, ends 117cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // CameraService::setTorchMode for camera ID 0 continues, calls 118cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // CameraFlashlight::setTorchMode 119cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk 120cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // TODO: Move torch status checks and state updates behind this CameraFlashlight lock 121cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk // to avoid other similar race conditions. 122cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk ALOGE("%s: Camera device %s is in use, cannot set torch mode.", 123cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk __FUNCTION__, cameraId.string()); 124cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk return -EBUSY; 125cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk } 126cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk 1273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mFlashControl == NULL) { 12888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (enabled == false) { 12988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 13088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 13188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 1323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = createFlashlightControl(cameraId); 1333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 1343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 1353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mFlashControl->setTorchMode(cameraId, enabled); 1373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 1383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 1403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // if flash control already exists, turning on torch mode may fail if it's 1413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // tied to another camera device for module v2.3 and below. 1423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mFlashControl->setTorchMode(cameraId, enabled); 1433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res == BAD_INDEX) { 1443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // flash control is tied to another camera device, need to close it and 1453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // try again. 1463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mFlashControl.clear(); 1473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = createFlashlightControl(cameraId); 1483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 1493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 1503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mFlashControl->setTorchMode(cameraId, enabled); 1523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 1543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 1553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 1563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 15788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::findFlashUnits() { 15888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen Mutex::Autolock l(mLock); 1593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res; 16088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int32_t numCameras = mCameraModule->getNumberOfCameras(); 1613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 16288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mHasFlashlightMap.clear(); 16388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashlightMapInitialized = false; 1643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 16588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (int32_t i = 0; i < numCameras; i++) { 16688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen bool hasFlash = false; 16788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen String8 id = String8::format("%d", i); 16888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 16988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = createFlashlightControl(id); 1703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 17188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: failed to create flash control for %s", __FUNCTION__, 17288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen id.string()); 17388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 17488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = mFlashControl->hasFlashUnit(id, &hasFlash); 17588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (res == -EUSERS || res == -EBUSY) { 17688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: failed to check if camera %s has a flash unit. Some " 17788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen "camera devices may be opened", __FUNCTION__, 17888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen id.string()); 17988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return res; 18088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else if (res) { 18188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: failed to check if camera %s has a flash unit. %s" 18288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen " (%d)", __FUNCTION__, id.string(), strerror(-res), 18388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res); 18488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 18588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 18688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl.clear(); 1873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 18888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mHasFlashlightMap.add(id, hasFlash); 1893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 1903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 19188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashlightMapInitialized = true; 19288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 19388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 1943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 19588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenbool CameraFlashlight::hasFlashUnit(const String8& cameraId) { 19688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen status_t res; 19788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 19888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen Mutex::Autolock l(mLock); 19988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return hasFlashUnitLocked(cameraId); 20088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 20188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 20288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenbool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) { 20388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 20432ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 20532ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 20688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return false; 2073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 2083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 20988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ssize_t index = mHasFlashlightMap.indexOfKey(cameraId); 21088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (index == NAME_NOT_FOUND) { 21188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: camera %s not present when findFlashUnits() was called", 21288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen __FUNCTION__, cameraId.string()); 21388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return false; 21488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 21588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 21688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return mHasFlashlightMap.valueAt(index); 2173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 2183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 21988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) { 2203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: prepare for device open", __FUNCTION__); 2213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 22388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 22432ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 22532ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 22688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return NO_INIT; 22788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 2283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 229676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) { 2303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // framework is going to open a camera device, all flash light control 2313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // should be closed for backward compatible support. 23288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl.clear(); 23388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 23488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.size() == 0) { 23588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // notify torch unavailable for all cameras with a flash 23688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int numCameras = mCameraModule->getNumberOfCameras(); 23788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (int i = 0; i < numCameras; i++) { 23888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (hasFlashUnitLocked(String8::format("%d", i))) { 23988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 24088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen String8::format("%d", i).string(), 24188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen TORCH_MODE_STATUS_NOT_AVAILABLE); 24288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 24388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 2443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 24588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 24688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // close flash control that may be opened by calling hasFlashUnitLocked. 24788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl.clear(); 24888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 24988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 25088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) { 25188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mOpenedCameraIds.add(cameraId); 2523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 2533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 2553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 2563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 25788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::deviceClosed(const String8& cameraId) { 25888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string()); 2593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 26088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen Mutex::Autolock l(mLock); 26188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 26232ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 26332ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 26488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return NO_INIT; 26588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 26688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 26788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ssize_t index = mOpenedCameraIds.indexOf(cameraId); 26888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (index == NAME_NOT_FOUND) { 26988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__, 27088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string()); 27188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 27288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mOpenedCameraIds.removeAt(index); 27388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 27488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 27588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // Cannot do anything until all cameras are closed. 27688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.size() != 0) 27788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 27888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 279676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) { 28088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // notify torch available for all cameras with a flash 28188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int numCameras = mCameraModule->getNumberOfCameras(); 28288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (int i = 0; i < numCameras; i++) { 28388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (hasFlashUnitLocked(String8::format("%d", i))) { 28488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 28588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen String8::format("%d", i).string(), 28688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen TORCH_MODE_STATUS_AVAILABLE_OFF); 28788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 28888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 28988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 29088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 29188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 2923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 29388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraFlashlight implementation ends 2943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 29688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenFlashControlBase::~FlashControlBase() { 29788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 29888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 29988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 30088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// ModuleFlashControl implementation begins 30188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// Flash control for camera module v2.4 and above. 30288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 30388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule, 3043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_module_callbacks_t& callbacks) : 3053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraModule(&cameraModule) { 3063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 30888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenModuleFlashControl::~ModuleFlashControl() { 3093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 31188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) { 3123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 3133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 3143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = false; 3173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 3183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 32088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), 3213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen &info); 3223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 3233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 3243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 3273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 3283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry flashAvailable = 3293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 3303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 3313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = true; 3323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 3353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 33788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) { 3383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__, 3393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string(), enabled); 3403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 34288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return mCameraModule->setTorchMode(cameraId.string(), enabled); 3433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 34488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// ModuleFlashControl implementation ends 3453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 34688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 34788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraDeviceClientFlashControl implementation begins 34888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// Flash control for camera module <= v2.3 and camera HAL v2-v3 34988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 3503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraDeviceClientFlashControl::CameraDeviceClientFlashControl( 3513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraModule& cameraModule, 3523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_module_callbacks_t& callbacks) : 3533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraModule(&cameraModule), 3543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCallbacks(&callbacks), 3553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mTorchEnabled(false), 35688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mMetadata(NULL), 35788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mStreaming(false) { 3583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { 36188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen disconnectCameraDevice(); 3623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata) { 3633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen delete mMetadata; 3643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 366727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface.clear(); 3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mSurfaceTexture.clear(); 3683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mProducer.clear(); 3693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mConsumer.clear(); 3703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mTorchEnabled) { 3723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mCallbacks) { 3733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: notify the framework that torch was turned off", 3743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen __FUNCTION__); 3753068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 37688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 3773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3803068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 38188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::initializeSurface( 38288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen sp<CameraDeviceBase> &device, int32_t width, int32_t height) { 3833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res; 3843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen BufferQueue::createBufferQueue(&mProducer, &mConsumer); 3853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 3873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen true, true); 3883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mSurfaceTexture == NULL) { 3893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 3903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 3933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mSurfaceTexture->setDefaultBufferSize(width, height); 3943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 3953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 3963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mSurfaceTexture->setDefaultBufferFormat(format); 3983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 3993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 402727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface = new Surface(mProducer, /*useAsync*/ true); 403727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala if (mSurface == NULL) { 4043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 4053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 406727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala res = device->createStream(mSurface, width, height, format, 407b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mStreamId); 4083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 41288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = device->configureStreams(); 4133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 4193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( 4213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_info& info, int32_t *width, int32_t *height) { 4223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!width || !height) { 4233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 4243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t w = INT32_MAX; 4273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t h = 1; 4283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 4303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 4313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry streamConfigs = 4323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); 4333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen for (size_t i = 0; i < streamConfigs.count; i += 4) { 4343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t fmt = streamConfigs.data.i32[i]; 4353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) { 4363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t ww = streamConfigs.data.i32[i + 1]; 4373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t hh = streamConfigs.data.i32[i + 2]; 4383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 43988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (w * h > ww * hh) { 44088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen w = ww; 44188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen h = hh; 44288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 44688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // if stream configuration is not found, try available processed sizes. 44788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (streamConfigs.count == 0) { 44888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen camera_metadata_entry availableProcessedSizes = 44988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES); 45088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (size_t i = 0; i < availableProcessedSizes.count; i += 2) { 45188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int32_t ww = availableProcessedSizes.data.i32[i]; 45288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int32_t hh = availableProcessedSizes.data.i32[i + 1]; 45388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (w * h > ww * hh) { 4543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen w = ww; 4553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen h = hh; 4563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (w == INT32_MAX) { 4613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NAME_NOT_FOUND; 4623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *width = w; 4653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *height = h; 4663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 4683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 4693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::connectCameraDevice( 47188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId) { 4723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 47388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); 4743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 4753068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 47688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string()); 4773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 48088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen sp<CameraDeviceBase> device = 48188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen CameraDeviceFactory::createDevice(atoi(cameraId.string())); 48288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (device == NULL) { 4833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 4843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 48688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = device->initialize(mCameraModule); 4873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 48888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return res; 4893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t width, height; 4923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = getSmallestSurfaceSize(info, &width, &height); 4933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 49688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = initializeSurface(device, width, height); 4973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 49888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return res; 4993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraId = cameraId; 50288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1); 50388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice = device; 5043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 50688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 5073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 50888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::disconnectCameraDevice() { 50988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mDevice != NULL) { 51088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice->disconnect(); 51188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice.clear(); 51288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 51388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 51488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 5153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 51888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 51988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId, 5203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen bool *hasFlash) { 5213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, 5223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string()); 5233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 5253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return hasFlashUnitLocked(cameraId, hasFlash); 5263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::hasFlashUnitLocked( 53088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId, bool *hasFlash) { 5313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 5323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 5333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 5363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = mCameraModule->getCameraInfo( 53788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen atoi(cameraId.string()), &info); 5383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 5393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 5403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string()); 5413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 5453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 5463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry flashAvailable = 5473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 5483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 5493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = true; 5503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 5533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 55588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() { 5563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res; 5573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata == NULL) { 5593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata = new CameraMetadata(); 5603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata == NULL) { 5613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 5623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mDevice->createDefaultRequest( 5643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CAMERA3_TEMPLATE_PREVIEW, mMetadata); 5653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 5663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 57088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen uint8_t torchOn = ANDROID_FLASH_MODE_TORCH; 5713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); 5723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); 5733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 57488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; 57588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); 57688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 5773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t requestId = 0; 5783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); 5793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 58088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mStreaming) { 58188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = mDevice->setStreamingRequest(*mMetadata); 58288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 58388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = mDevice->capture(*mMetadata); 58488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 5853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 58988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 59088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 5913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::setTorchMode( 59288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId, bool enabled) { 5933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen bool hasFlash = false; 5943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 5963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = hasFlashUnitLocked(cameraId, &hasFlash); 5973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // pre-check 5993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (enabled) { 6003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // invalid camera? 6013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return -EINVAL; 6033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // no flash unit? 6053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 6063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return -ENOSYS; 6073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // already opened for a different device? 6093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mDevice != NULL && cameraId != mCameraId) { 6103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_INDEX; 6113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } else if (mDevice == NULL || cameraId != mCameraId) { 6133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // disabling the torch mode of an un-opened or different device. 6143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 61588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 61688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // disabling the torch mode of currently opened device 61788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen disconnectCameraDevice(); 61888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mTorchEnabled = false; 61988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 62088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 62188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 6223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 6243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mDevice == NULL) { 6253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = connectCameraDevice(cameraId); 6263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 6283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 63188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = submitTorchEnabledRequest(); 6323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 6343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 63688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mTorchEnabled = true; 63788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 63888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 6393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 6403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 64188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraDeviceClientFlashControl implementation ends 6423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 643d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 644d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen///////////////////////////////////////////////////////////////////// 645d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// CameraHardwareInterfaceFlashControl implementation begins 646d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// Flash control for camera module <= v2.3 and camera HAL v1 647d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen///////////////////////////////////////////////////////////////////// 648d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu ChenCameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( 649d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen CameraModule& cameraModule, 650d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const camera_module_callbacks_t& callbacks) : 651d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraModule(&cameraModule), 652d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks(&callbacks), 653d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled(false) { 654d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 655d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 656d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 657d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu ChenCameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { 658d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen disconnectCameraDevice(); 659d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 660727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface.clear(); 661d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mSurfaceTexture.clear(); 662d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mProducer.clear(); 663d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mConsumer.clear(); 664d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 665d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mTorchEnabled) { 666d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mCallbacks) { 667d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGV("%s: notify the framework that torch was turned off", 668d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__); 669d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 670d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 671d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 672d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 673d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 674d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 675d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::setTorchMode( 676d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId, bool enabled) { 677d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Mutex::Autolock l(mLock); 678d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 679d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // pre-check 680d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 681d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (enabled) { 682d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen bool hasFlash = false; 683d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = hasFlashUnitLocked(cameraId, &hasFlash); 684d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // invalid camera? 685d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 686d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to 687d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // another camera device. 688d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res == BAD_INDEX ? BAD_INDEX : -EINVAL; 689d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 690d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // no flash unit? 691d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (!hasFlash) { 692d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return -ENOSYS; 693d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 694d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else if (mDevice == NULL || cameraId != mCameraId) { 695d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // disabling the torch mode of an un-opened or different device. 696d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 697d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else { 698d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // disabling the torch mode of currently opened device 699d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen disconnectCameraDevice(); 700d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled = false; 701d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 702d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 703d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 704d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 705d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 706d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = startPreviewAndTorch(); 707d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 708d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 709d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 710d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 711d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled = true; 712d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 713d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 714d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 715d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 716d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 717d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::hasFlashUnit( 718d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId, bool *hasFlash) { 719d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Mutex::Autolock l(mLock); 720d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return hasFlashUnitLocked(cameraId, hasFlash); 721d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 722d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 723d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( 724d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId, bool *hasFlash) { 725d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (!hasFlash) { 726d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_VALUE; 727d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 728d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 729d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 730d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mDevice == NULL) { 731d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = connectCameraDevice(cameraId); 732d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 733d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 734d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 735d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 736d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 737d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (cameraId != mCameraId) { 738d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_INDEX; 739d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 740d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 741d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const char *flashMode = 742d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); 743d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { 744d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *hasFlash = true; 745d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else { 746d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *hasFlash = false; 747d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 748d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 749d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 750d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 751d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 752d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { 753d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res = OK; 754d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mDevice->startPreview(); 755d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 756d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, 757d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen strerror(-res), res); 758d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 759d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 760d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 761d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.set(CameraParameters::KEY_FLASH_MODE, 762d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen CameraParameters::FLASH_MODE_TORCH); 763d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 764d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return mDevice->setParameters(mParameters); 765d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 766d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 767d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( 768d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t *width, int32_t *height) { 769d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (!width || !height) { 770d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_VALUE; 771d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 772d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 773d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t w = INT32_MAX; 774d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t h = 1; 775d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Vector<Size> sizes; 776d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 777d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.getSupportedPreviewSizes(sizes); 778d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen for (size_t i = 0; i < sizes.size(); i++) { 779d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Size s = sizes[i]; 780d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (w * h > s.width * s.height) { 781d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen w = s.width; 782d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen h = s.height; 783d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 784d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 785d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 786d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (w == INT32_MAX) { 787d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NAME_NOT_FOUND; 788d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 789d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 790d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *width = w; 791d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *height = h; 792d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 793d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 794d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 795d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 796d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( 797d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen sp<CameraHardwareInterface> device, int32_t width, int32_t height) { 798d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 799d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen BufferQueue::createBufferQueue(&mProducer, &mConsumer); 800d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 801d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 802d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen true, true); 803d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mSurfaceTexture == NULL) { 804d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NO_MEMORY; 805d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 806d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 807d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 808d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mSurfaceTexture->setDefaultBufferSize(width, height); 809d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 810d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 811d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 812d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mSurfaceTexture->setDefaultBufferFormat(format); 813d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 814d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 815d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 816d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 817727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface = new Surface(mProducer, /*useAsync*/ true); 818727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala if (mSurface == NULL) { 819d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NO_MEMORY; 820d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 821d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 822727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala res = native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_CAMERA); 823d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 824d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: Unable to connect to native window", __FUNCTION__); 825d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 826d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 827d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 828727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala return device->setPreviewWindow(mSurface); 829d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 830d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 831d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::connectCameraDevice( 832d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId) { 833d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen sp<CameraHardwareInterface> device = 834d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen new CameraHardwareInterface(cameraId.string()); 835d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 836d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res = device->initialize(mCameraModule); 837d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 838d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: initializing camera %s failed", __FUNCTION__, 839d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string()); 840d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 841d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 842d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 843d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // need to set __get_memory in set_callbacks(). 844d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen device->setCallbacks(NULL, NULL, NULL, NULL); 845d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 846d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters = device->getParameters(); 847d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 848d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t width, height; 849d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = getSmallestSurfaceSize(&width, &height); 850d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 851d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: failed to get smallest surface size for camera %s", 852d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, cameraId.string()); 853d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 854d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 855d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 856d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = initializePreviewWindow(device, width, height); 857d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 858d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: failed to initialize preview window for camera %s", 859d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, cameraId.string()); 860d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 861d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 862d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 863d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraId = cameraId; 864d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice = device; 865d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 866d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 867d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 868d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { 869d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mDevice == NULL) { 870d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 871d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 872d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 873d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.set(CameraParameters::KEY_FLASH_MODE, 874d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen CameraParameters::FLASH_MODE_OFF); 875d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->setParameters(mParameters); 876d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->stopPreview(); 877727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala status_t res = native_window_api_disconnect(mSurface.get(), 878d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen NATIVE_WINDOW_API_CAMERA); 879d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 880d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGW("%s: native_window_api_disconnect failed: %s (%d)", 881d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, strerror(-res), res); 882d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 883d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->setPreviewWindow(NULL); 884d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->release(); 8858a4a0ac6545f53a9ec4af6074caf0e935b08ffbeOleksiy Avramchenko mDevice = NULL; 886d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 887d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 888d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 889d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// CameraHardwareInterfaceFlashControl implementation ends 890d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 8913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 892