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