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" 30d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala#include "device3/Camera3Device.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 81d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_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 Mutex::Autolock l(mLock); 19788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return hasFlashUnitLocked(cameraId); 19888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 19988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 20088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenbool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) { 20188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 20232ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 20332ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 20488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return false; 2053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 2063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 20788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ssize_t index = mHasFlashlightMap.indexOfKey(cameraId); 20888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (index == NAME_NOT_FOUND) { 20988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: camera %s not present when findFlashUnits() was called", 21088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen __FUNCTION__, cameraId.string()); 21188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return false; 21288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 21388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 21488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return mHasFlashlightMap.valueAt(index); 2153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 2163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 21788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) { 2183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: prepare for device open", __FUNCTION__); 2193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 22188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 22232ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 22332ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 22488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return NO_INIT; 22588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 2263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 227676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) { 2283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // framework is going to open a camera device, all flash light control 2293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // should be closed for backward compatible support. 23088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl.clear(); 23188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 23288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.size() == 0) { 23388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // notify torch unavailable for all cameras with a flash 23488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int numCameras = mCameraModule->getNumberOfCameras(); 23588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (int i = 0; i < numCameras; i++) { 23688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (hasFlashUnitLocked(String8::format("%d", i))) { 23788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 23888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen String8::format("%d", i).string(), 23988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen TORCH_MODE_STATUS_NOT_AVAILABLE); 24088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 24188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 2423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 24388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 24488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // close flash control that may be opened by calling hasFlashUnitLocked. 24588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mFlashControl.clear(); 24688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 24788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 24888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) { 24988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mOpenedCameraIds.add(cameraId); 2503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 2513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 2533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 2543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 25588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraFlashlight::deviceClosed(const String8& cameraId) { 25688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string()); 2573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 25888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen Mutex::Autolock l(mLock); 25988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (!mFlashlightMapInitialized) { 26032ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda ALOGE("%s: findFlashUnits() must be called before this method.", 26132ab9fdab562127ccd37a8cdb15421ebdf82a458Ranjith Kagathi Ananda __FUNCTION__); 26288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return NO_INIT; 26388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 26488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 26588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ssize_t index = mOpenedCameraIds.indexOf(cameraId); 26688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (index == NAME_NOT_FOUND) { 26788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__, 26888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string()); 26988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 27088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mOpenedCameraIds.removeAt(index); 27188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 27288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 27388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // Cannot do anything until all cameras are closed. 27488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mOpenedCameraIds.size() != 0) 27588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 27688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 277676b21b30edbd74d7b9aae247961a1ffde1b8993Chien-Yu Chen if (mCameraModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_4) { 27888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // notify torch available for all cameras with a flash 27988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int numCameras = mCameraModule->getNumberOfCameras(); 28088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (int i = 0; i < numCameras; i++) { 28188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (hasFlashUnitLocked(String8::format("%d", i))) { 28288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 28388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen String8::format("%d", i).string(), 28488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen TORCH_MODE_STATUS_AVAILABLE_OFF); 28588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 28688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 28788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 28888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 28988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 2903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 29188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraFlashlight implementation ends 2923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 2933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 29488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenFlashControlBase::~FlashControlBase() { 29588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 29688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 29788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 29888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// ModuleFlashControl implementation begins 29988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// Flash control for camera module v2.4 and above. 30088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 30188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule, 3023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_module_callbacks_t& callbacks) : 303d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala mCameraModule(&cameraModule) { 304d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala (void) callbacks; 3053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 30788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu ChenModuleFlashControl::~ModuleFlashControl() { 3083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 31088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) { 3113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 3123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 3133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = false; 3163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 3173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 31988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), 3203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen &info); 3213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 3223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 3233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 3263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 3273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry flashAvailable = 3283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 3293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 3303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = true; 3313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 3343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 33688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) { 3373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__, 3383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string(), enabled); 3393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 34188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return mCameraModule->setTorchMode(cameraId.string(), enabled); 3423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 34388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// ModuleFlashControl implementation ends 3443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 34588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 34688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraDeviceClientFlashControl implementation begins 34788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// Flash control for camera module <= v2.3 and camera HAL v2-v3 34888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen///////////////////////////////////////////////////////////////////// 3493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraDeviceClientFlashControl::CameraDeviceClientFlashControl( 3503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraModule& cameraModule, 3513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_module_callbacks_t& callbacks) : 3523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraModule(&cameraModule), 3533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCallbacks(&callbacks), 3543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mTorchEnabled(false), 35588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mMetadata(NULL), 35688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mStreaming(false) { 3573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu ChenCameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { 36088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen disconnectCameraDevice(); 3613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata) { 3623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen delete mMetadata; 3633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 365727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface.clear(); 3663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mSurfaceTexture.clear(); 3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mProducer.clear(); 3683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mConsumer.clear(); 3693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mTorchEnabled) { 3713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mCallbacks) { 3723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: notify the framework that torch was turned off", 3733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen __FUNCTION__); 3743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 37588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 3763068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 3793068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 38088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::initializeSurface( 38188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen sp<CameraDeviceBase> &device, int32_t width, int32_t height) { 3823068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res; 3833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen BufferQueue::createBufferQueue(&mProducer, &mConsumer); 3843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 3863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen true, true); 3873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mSurfaceTexture == NULL) { 3883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 3893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 3913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 3923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mSurfaceTexture->setDefaultBufferSize(width, height); 3933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 3943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 3953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 3963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mSurfaceTexture->setDefaultBufferFormat(format); 3973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 3983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 3993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 401727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface = new Surface(mProducer, /*useAsync*/ true); 402727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala if (mSurface == NULL) { 4033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 4043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 405727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala res = device->createStream(mSurface, width, height, format, 406b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mStreamId); 4073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 41188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = device->configureStreams(); 4123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4173068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 4183068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( 4203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen const camera_info& info, int32_t *width, int32_t *height) { 4213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!width || !height) { 4223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 4233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t w = INT32_MAX; 4263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t h = 1; 4273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 4293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 4303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry streamConfigs = 4313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); 4323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen for (size_t i = 0; i < streamConfigs.count; i += 4) { 4333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t fmt = streamConfigs.data.i32[i]; 4343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) { 4353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t ww = streamConfigs.data.i32[i + 1]; 4363068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t hh = streamConfigs.data.i32[i + 2]; 4373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 43888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (w * h > ww * hh) { 43988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen w = ww; 44088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen h = hh; 44188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 44488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 44588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // if stream configuration is not found, try available processed sizes. 44688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (streamConfigs.count == 0) { 44788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen camera_metadata_entry availableProcessedSizes = 44888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES); 44988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen for (size_t i = 0; i < availableProcessedSizes.count; i += 2) { 45088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int32_t ww = availableProcessedSizes.data.i32[i]; 45188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen int32_t hh = availableProcessedSizes.data.i32[i + 1]; 45288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (w * h > ww * hh) { 4533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen w = ww; 4543068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen h = hh; 4553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (w == INT32_MAX) { 4603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NAME_NOT_FOUND; 4613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *width = w; 4643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *height = h; 4653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 4673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 4683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4693068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::connectCameraDevice( 47088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId) { 4713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 47288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); 4733068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 4743068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 47588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string()); 4763068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 47988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen sp<CameraDeviceBase> device = 480d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala new Camera3Device(atoi(cameraId.string())); 48188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (device == NULL) { 4823068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 4833068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 48588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = device->initialize(mCameraModule); 4863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 48788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return res; 4883068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4893068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 4903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t width, height; 4913068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = getSmallestSurfaceSize(info, &width, &height); 4923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 4933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 4943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 49588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = initializeSurface(device, width, height); 4963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 49788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return res; 4983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 4993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mCameraId = cameraId; 50188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1); 50288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice = device; 5033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 50588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen} 5063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 50788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::disconnectCameraDevice() { 50888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mDevice != NULL) { 50988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice->disconnect(); 51088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mDevice.clear(); 51188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 51288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 51388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 5143068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5153068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5163068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 51788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 51888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId, 5193068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen bool *hasFlash) { 5203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, 5213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string()); 5223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 5243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return hasFlashUnitLocked(cameraId, hasFlash); 5253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::hasFlashUnitLocked( 52988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId, bool *hasFlash) { 5303068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 5313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_VALUE; 5323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_info info; 5353068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = mCameraModule->getCameraInfo( 53688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen atoi(cameraId.string()), &info); 5373068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res != 0) { 5383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, 5393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen cameraId.string()); 5403068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CameraMetadata metadata; 5443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata = info.static_camera_characteristics; 5453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen camera_metadata_entry flashAvailable = 5463068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen metadata.find(ANDROID_FLASH_INFO_AVAILABLE); 5473068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { 5483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen *hasFlash = true; 5493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5513068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 5523068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5533068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 55488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() { 5553068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res; 5563068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5573068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata == NULL) { 5583068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata = new CameraMetadata(); 5593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mMetadata == NULL) { 5603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return NO_MEMORY; 5613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5623068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = mDevice->createDefaultRequest( 5633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen CAMERA3_TEMPLATE_PREVIEW, mMetadata); 5643068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 5653068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 5683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 56988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen uint8_t torchOn = ANDROID_FLASH_MODE_TORCH; 5703068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); 5713068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); 5723068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 57388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; 57488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); 57588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 5763068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen int32_t requestId = 0; 5773068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); 5783068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 57988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen if (mStreaming) { 58088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = mDevice->setStreamingRequest(*mMetadata); 58188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 58288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = mDevice->capture(*mMetadata); 58388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } 5843068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 5853068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 5863068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5873068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 58888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 58988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen 5903068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t CameraDeviceClientFlashControl::setTorchMode( 59188da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen const String8& cameraId, bool enabled) { 5923068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen bool hasFlash = false; 5933068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5943068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen Mutex::Autolock l(mLock); 5953068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen status_t res = hasFlashUnitLocked(cameraId, &hasFlash); 5963068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 5973068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // pre-check 5983068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (enabled) { 5993068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // invalid camera? 6003068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6013068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return -EINVAL; 6023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // no flash unit? 6043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (!hasFlash) { 6053068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return -ENOSYS; 6063068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6073068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // already opened for a different device? 6083068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mDevice != NULL && cameraId != mCameraId) { 6093068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return BAD_INDEX; 6103068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6113068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } else if (mDevice == NULL || cameraId != mCameraId) { 6123068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen // disabling the torch mode of an un-opened or different device. 6133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 61488da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen } else { 61588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen // disabling the torch mode of currently opened device 61688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen disconnectCameraDevice(); 61788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mTorchEnabled = false; 61888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 61988da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 62088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen return OK; 6213068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6223068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 6233068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (mDevice == NULL) { 6243068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen res = connectCameraDevice(cameraId); 6253068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6263068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 6273068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6283068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6293068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 63088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen res = submitTorchEnabledRequest(); 6313068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen if (res) { 6323068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return res; 6333068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen } 6343068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 63588da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mTorchEnabled = true; 63688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 63788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 6383068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen return OK; 6393068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 64088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen// CameraDeviceClientFlashControl implementation ends 6413068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen 642d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 643d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen///////////////////////////////////////////////////////////////////// 644d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// CameraHardwareInterfaceFlashControl implementation begins 645d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// Flash control for camera module <= v2.3 and camera HAL v1 646d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen///////////////////////////////////////////////////////////////////// 647d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu ChenCameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( 648d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen CameraModule& cameraModule, 649d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const camera_module_callbacks_t& callbacks) : 650d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraModule(&cameraModule), 651d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks(&callbacks), 652d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled(false) { 653d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 654d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 655d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 656d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu ChenCameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { 657d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen disconnectCameraDevice(); 658d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 659727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface.clear(); 660d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mSurfaceTexture.clear(); 661d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mProducer.clear(); 662d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mConsumer.clear(); 663d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 664d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mTorchEnabled) { 665d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mCallbacks) { 666d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGV("%s: notify the framework that torch was turned off", 667d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__); 668d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 669d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 670d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 671d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 672d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 673d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 674d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::setTorchMode( 675d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId, bool enabled) { 676d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Mutex::Autolock l(mLock); 677d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 678d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // pre-check 679d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 680d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (enabled) { 681d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen bool hasFlash = false; 6826dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // Check if it has a flash unit and leave camera device open. 6836dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true); 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) { 6926dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // Disconnect camera device if it has no flash. 6936dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen disconnectCameraDevice(); 694d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return -ENOSYS; 695d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 696d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else if (mDevice == NULL || cameraId != mCameraId) { 697d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // disabling the torch mode of an un-opened or different device. 698d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 699d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else { 700d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // disabling the torch mode of currently opened device 701d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen disconnectCameraDevice(); 702d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled = false; 703d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 704d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); 705d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 706d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 707d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 708d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = startPreviewAndTorch(); 709d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 710d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 711d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 712d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 713d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mTorchEnabled = true; 714d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCallbacks->torch_mode_status_change(mCallbacks, 715d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); 716d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 717d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 718d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 719d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::hasFlashUnit( 720d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId, bool *hasFlash) { 721d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Mutex::Autolock l(mLock); 7226dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // Close device after checking if it has a flash unit. 7236dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false); 724d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 725d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 726d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( 7276dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) { 7286dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen bool closeCameraDevice = false; 7296dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen 730d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (!hasFlash) { 731d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_VALUE; 732d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 733d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 734d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 735d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mDevice == NULL) { 7366dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // Connect to camera device to query if it has a flash unit. 737d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = connectCameraDevice(cameraId); 738d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 739d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 740d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 7416dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // Close camera device only when it is just opened and the caller doesn't want to keep 7426dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen // the camera device open. 7436dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen closeCameraDevice = !keepDeviceOpen; 744d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 745d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 746d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (cameraId != mCameraId) { 747d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_INDEX; 748d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 749d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 750d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const char *flashMode = 751d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); 752d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { 753d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *hasFlash = true; 754d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } else { 755d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *hasFlash = false; 756d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 757d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 7586dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen if (closeCameraDevice) { 7596dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen res = disconnectCameraDevice(); 7606dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen if (res != OK) { 7616dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__, 7626dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen strerror(-res), res); 7636dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen return res; 7646dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen } 7656dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen } 7666dcc706b3b06eedcc8d24a3001543c3f49999d94Chien-Yu Chen 767d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 768d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 769d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 770d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { 771d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res = OK; 772d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mDevice->startPreview(); 773d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 774d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, 775d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen strerror(-res), res); 776d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 777d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 778d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 779d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.set(CameraParameters::KEY_FLASH_MODE, 780d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen CameraParameters::FLASH_MODE_TORCH); 781d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 782d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return mDevice->setParameters(mParameters); 783d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 784d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 785d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( 786d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t *width, int32_t *height) { 787d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (!width || !height) { 788d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return BAD_VALUE; 789d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 790d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 791d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t w = INT32_MAX; 792d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t h = 1; 793d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Vector<Size> sizes; 794d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 795d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters.getSupportedPreviewSizes(sizes); 796d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen for (size_t i = 0; i < sizes.size(); i++) { 797d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen Size s = sizes[i]; 798d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (w * h > s.width * s.height) { 799d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen w = s.width; 800d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen h = s.height; 801d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 802d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 803d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 804d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (w == INT32_MAX) { 805d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NAME_NOT_FOUND; 806d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 807d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 808d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *width = w; 809d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen *height = h; 810d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 811d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 812d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 813d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 814d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( 815d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen sp<CameraHardwareInterface> device, int32_t width, int32_t height) { 816d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res; 817d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen BufferQueue::createBufferQueue(&mProducer, &mConsumer); 818d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 819d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, 820d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen true, true); 821d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mSurfaceTexture == NULL) { 822d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NO_MEMORY; 823d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 824d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 825d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 826d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mSurfaceTexture->setDefaultBufferSize(width, height); 827d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 828d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 829d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 830d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = mSurfaceTexture->setDefaultBufferFormat(format); 831d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 832d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 833d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 834d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 835727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala mSurface = new Surface(mProducer, /*useAsync*/ true); 836727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala if (mSurface == NULL) { 837d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return NO_MEMORY; 838d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 839d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 840727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala res = native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_CAMERA); 841d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 842d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: Unable to connect to native window", __FUNCTION__); 843d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 844d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 845d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 846727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala return device->setPreviewWindow(mSurface); 847d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 848d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 849d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::connectCameraDevice( 850d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen const String8& cameraId) { 851d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen sp<CameraHardwareInterface> device = 852d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen new CameraHardwareInterface(cameraId.string()); 853d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 854d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen status_t res = device->initialize(mCameraModule); 855d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 856d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: initializing camera %s failed", __FUNCTION__, 857d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen cameraId.string()); 858d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 859d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 860d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 861d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen // need to set __get_memory in set_callbacks(). 862d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen device->setCallbacks(NULL, NULL, NULL, NULL); 863d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 864d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mParameters = device->getParameters(); 865d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 866d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen int32_t width, height; 867d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = getSmallestSurfaceSize(&width, &height); 868d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 869d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: failed to get smallest surface size for camera %s", 870d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, cameraId.string()); 871d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 872d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 873d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 874d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen res = initializePreviewWindow(device, width, height); 875d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 876d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGE("%s: failed to initialize preview window for camera %s", 877d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, cameraId.string()); 878d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return res; 879d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 880d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 881d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mCameraId = cameraId; 882d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice = device; 883d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 884d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 885d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 886d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chenstatus_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { 887d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (mDevice == NULL) { 888d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 889d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 890d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 8913d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) { 8923d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye // There is a flash, turn if off. 8933d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye // (If there isn't one, leave the parameter null) 8943d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye mParameters.set(CameraParameters::KEY_FLASH_MODE, 8953d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye CameraParameters::FLASH_MODE_OFF); 8963d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye mDevice->setParameters(mParameters); 8973d1c478fc34824db4e68d50c12f283d6b55c272eJim Kaye } 898d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->stopPreview(); 899727d172137b4f32681c098de8e2623c0b65a6406Eino-Ville Talvala status_t res = native_window_api_disconnect(mSurface.get(), 900d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen NATIVE_WINDOW_API_CAMERA); 901d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen if (res) { 902d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen ALOGW("%s: native_window_api_disconnect failed: %s (%d)", 903d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen __FUNCTION__, strerror(-res), res); 904d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen } 905d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->setPreviewWindow(NULL); 906d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen mDevice->release(); 9078a4a0ac6545f53a9ec4af6074caf0e935b08ffbeOleksiy Avramchenko mDevice = NULL; 908d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 909d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen return OK; 910d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen} 911d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen// CameraHardwareInterfaceFlashControl implementation ends 912d231fd61ca94441183abda9766ce6906a5b4c3cfChien-Yu Chen 9133068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen} 914