Parameters.cpp revision 9078a1b3b9f9c0c48046ade0e8e18b0d79a659db
18f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall/*
28f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * Copyright (C) 2012 The Android Open Source Project
38f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall *
48f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * Licensed under the Apache License, Version 2.0 (the "License");
58f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * you may not use this file except in compliance with the License.
68f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * You may obtain a copy of the License at
78f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall *
88f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall *      http://www.apache.org/licenses/LICENSE-2.0
98f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall *
108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * Unless required by applicable law or agreed to in writing, software
118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * distributed under the License is distributed on an "AS IS" BASIS,
128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall * See the License for the specific language governing permissions and
14dc7b641574a733624489bd87fc7061771edf2113Douglas Gregor * limitations under the License.
158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall */
16684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis
17dc7b641574a733624489bd87fc7061771edf2113Douglas Gregor#define LOG_TAG "Camera2-Parameters"
188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#define ATRACE_TAG ATRACE_TAG_CAMERA
198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// #define LOG_NDEBUG 0
208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <utils/Log.h>
228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <utils/Trace.h>
238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <utils/Vector.h>
248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <utils/SortedVector.h>
258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <math.h>
278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <stdlib.h>
288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include <cutils/properties.h>
298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "Parameters.h"
318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "system/camera.h"
322d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner
332d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattnernamespace android {
348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallnamespace camera2 {
35d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie
36e665d6929e11796620ff799bc0186ebd747bfc76Argyrios KyrtzidisParameters::Parameters(int cameraId,
37e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis        int cameraFacing) :
387ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis        cameraId(cameraId),
397ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis        cameraFacing(cameraFacing),
407ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis        info(NULL) {
417ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis}
428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallParameters::~Parameters() {
447ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis}
452d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner
467ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidisstatus_t Parameters::initialize(const CameraMetadata *info) {
477ee2049278b98d42709380054eb83f4952af1200Argyrios Kyrtzidis    status_t res;
488f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
49d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    if (info->entryCount() == 0) {
508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        ALOGE("%s: No static information provided!", __FUNCTION__);
518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        return BAD_VALUE;
528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    }
538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    Parameters::info = info;
54d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie
558f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    res = buildFastInfo();
568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    if (res != OK) return res;
578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    res = buildQuirks();
598f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    if (res != OK) return res;
608f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    const Size MAX_PREVIEW_SIZE = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
62686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    res = getFilteredPreviewSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
63686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    if (res != OK) return res;
648f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    // TODO: Pick more intelligently
66686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    previewWidth = availablePreviewSizes[0].width;
678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    previewHeight = availablePreviewSizes[0].height;
68686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    videoWidth = previewWidth;
69686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    videoHeight = previewHeight;
70686775deca8b8685eb90801495880e3abdd844c2Chris Lattner
718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    params.setPreviewSize(previewWidth, previewHeight);
728f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    params.setVideoSize(videoWidth, videoHeight);
738f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
742d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner            String8::format("%dx%d",
758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    previewWidth, previewHeight));
762d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner    {
778f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        String8 supportedPreviewSizes;
788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        for (size_t i = 0; i < availablePreviewSizes.size(); i++) {
798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            if (i != 0) supportedPreviewSizes += ",";
808f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            supportedPreviewSizes += String8::format("%dx%d",
818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    availablePreviewSizes[i].width,
828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    availablePreviewSizes[i].height);
838f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        }
848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.string());
858f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewSizes);
878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewSizes);
898f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    }
908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    camera_metadata_ro_entry_t availableFpsRanges =
928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    if (!availableFpsRanges.count) return NO_INIT;
948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            formatEnumToString(previewFormat)); // NV21
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
99686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    previewTransform = degToTransform(0,
1008f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            cameraFacing == CAMERA_FACING_FRONT);
101b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian
102b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian    camera_metadata_ro_entry_t availableFormats =
103686775deca8b8685eb90801495880e3abdd844c2Chris Lattner        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
1058f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    {
106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        String8 supportedPreviewFormats;
107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        bool addComma = false;
108ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        for (size_t i=0; i < availableFormats.count; i++) {
109fd10398c10ffdcbdeb1e3e299c74d70e689f503cArgyrios Kyrtzidis            if (addComma) supportedPreviewFormats += ",";
1108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            addComma = true;
1118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            switch (availableFormats.data.i32[i]) {
1128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
114686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                    CameraParameters::PIXEL_FORMAT_YUV422SP;
1158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_YUV420SP;
1198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_YCbCr_422_I:
1218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_YUV422I;
1238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_YV12:
1258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_YUV420P;
1278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_RGB_565:
1298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_RGB565;
1318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_RGBA_8888:
1338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_RGBA8888;
1358f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_YCbCr_420_888:
1378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                // Flexible YUV allows both YV12 and NV21
1388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_YUV420P;
1408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats += ",";
1418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats +=
1428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    CameraParameters::PIXEL_FORMAT_YUV420SP;
1438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
1448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
1458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
1468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_RAW_SENSOR:
1478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            case HAL_PIXEL_FORMAT_BLOB:
148e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis                addComma = false;
149b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian                break;
1508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
1518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            default:
152ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis                ALOGW("%s: Camera %d: Unknown preview format: %x",
1538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                        __FUNCTION__, cameraId, availableFormats.data.i32[i]);
154dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie                addComma = false;
1558f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                break;
156e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis            }
157e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis        }
158ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1598f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                supportedPreviewFormats);
160b5c6babd3d8e0233b8ea5a4eb1e2700e30c0d396Fariborz Jahanian    }
161ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
162e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    previewFpsRange[0] = availableFpsRanges.data.i32[0];
163e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    previewFpsRange[1] = availableFpsRanges.data.i32[1];
164ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
165ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
166e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis    // still have to do something sane for them
16726f0e4e7ab534fb42485c930f20a424ecc8c9830Fariborz Jahanian
16826f0e4e7ab534fb42485c930f20a424ecc8c9830Fariborz Jahanian    // NOTE: Not scaled like FPS range values are.
169684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis    int previewFps = fpsFromRange(previewFpsRange[0], previewFpsRange[1]);
170684190b8dbe5258f4708ffbd816b8c5ee5b3502dArgyrios Kyrtzidis    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
1718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            previewFps);
1728f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
173686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    // PREVIEW_FPS_RANGE
1748f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    // -- Order matters. Set range after single value to so that a roundtrip
1758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    //    of setParameters(getParameters()) would keep the FPS range in higher
1768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    //    order.
1778f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall            String8::format("%d,%d",
1798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    previewFpsRange[0] * kFpsToApiScale,
1808f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall                    previewFpsRange[1] * kFpsToApiScale));
1818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall
182    {
183        String8 supportedPreviewFpsRange;
184        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
185            if (i != 0) supportedPreviewFpsRange += ",";
186            supportedPreviewFpsRange += String8::format("(%d,%d)",
187                    availableFpsRanges.data.i32[i] * kFpsToApiScale,
188                    availableFpsRanges.data.i32[i+1] * kFpsToApiScale);
189        }
190        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
191                supportedPreviewFpsRange);
192    }
193
194    {
195        SortedVector<int32_t> sortedPreviewFrameRates;
196
197        String8 supportedPreviewFrameRates;
198        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
199            // from the [min, max] fps range use the max value
200            int fps = fpsFromRange(availableFpsRanges.data.i32[i],
201                                   availableFpsRanges.data.i32[i+1]);
202
203            // de-dupe frame rates
204            if (sortedPreviewFrameRates.indexOf(fps) == NAME_NOT_FOUND) {
205                sortedPreviewFrameRates.add(fps);
206            }
207            else {
208                continue;
209            }
210
211            if (sortedPreviewFrameRates.size() > 1) {
212                supportedPreviewFrameRates += ",";
213            }
214
215            supportedPreviewFrameRates += String8::format("%d",
216                    fps);
217
218            ALOGV("%s: Supported preview frame rates: %s",
219                    __FUNCTION__, supportedPreviewFrameRates.string());
220        }
221        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
222                supportedPreviewFrameRates);
223    }
224
225    camera_metadata_ro_entry_t availableJpegSizes =
226        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
227    if (!availableJpegSizes.count) return NO_INIT;
228
229    // TODO: Pick maximum
230    pictureWidth = availableJpegSizes.data.i32[0];
231    pictureHeight = availableJpegSizes.data.i32[1];
232
233    params.setPictureSize(pictureWidth,
234            pictureHeight);
235
236    {
237        String8 supportedPictureSizes;
238        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
239            if (i != 0) supportedPictureSizes += ",";
240            supportedPictureSizes += String8::format("%dx%d",
241                    availableJpegSizes.data.i32[i],
242                    availableJpegSizes.data.i32[i+1]);
243        }
244        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
245                supportedPictureSizes);
246    }
247
248    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
249    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
250            CameraParameters::PIXEL_FORMAT_JPEG);
251
252    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
253        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 4);
254    if (!availableJpegThumbnailSizes.count) return NO_INIT;
255
256    // Pick the largest thumbnail size that matches still image aspect ratio.
257    ALOG_ASSERT(pictureWidth > 0 && pictureHeight > 0,
258            "Invalid picture size, %d x %d", pictureWidth, pictureHeight);
259    float picAspectRatio = static_cast<float>(pictureWidth) / pictureHeight;
260    Size thumbnailSize =
261            getMaxSizeForRatio(
262                    picAspectRatio,
263                    &availableJpegThumbnailSizes.data.i32[0],
264                    availableJpegThumbnailSizes.count);
265    jpegThumbSize[0] = thumbnailSize.width;
266    jpegThumbSize[1] = thumbnailSize.height;
267
268    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
269            jpegThumbSize[0]);
270    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
271            jpegThumbSize[1]);
272
273    {
274        String8 supportedJpegThumbSizes;
275        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
276            if (i != 0) supportedJpegThumbSizes += ",";
277            supportedJpegThumbSizes += String8::format("%dx%d",
278                    availableJpegThumbnailSizes.data.i32[i],
279                    availableJpegThumbnailSizes.data.i32[i+1]);
280        }
281        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
282                supportedJpegThumbSizes);
283    }
284
285    jpegThumbQuality = 90;
286    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
287            jpegThumbQuality);
288    jpegQuality = 90;
289    params.set(CameraParameters::KEY_JPEG_QUALITY,
290            jpegQuality);
291    jpegRotation = 0;
292    params.set(CameraParameters::KEY_ROTATION,
293            jpegRotation);
294
295    gpsEnabled = false;
296    gpsCoordinates[0] = 0.0;
297    gpsCoordinates[1] = 0.0;
298    gpsCoordinates[2] = 0.0;
299    gpsTimestamp = 0;
300    gpsProcessingMethod = "unknown";
301    // GPS fields in CameraParameters are not set by implementation
302
303    wbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
304    params.set(CameraParameters::KEY_WHITE_BALANCE,
305            CameraParameters::WHITE_BALANCE_AUTO);
306
307    camera_metadata_ro_entry_t availableWhiteBalanceModes =
308        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES, 0, 0, false);
309    if (!availableWhiteBalanceModes.count) {
310        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
311                CameraParameters::WHITE_BALANCE_AUTO);
312    } else {
313        String8 supportedWhiteBalance;
314        bool addComma = false;
315        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
316            if (addComma) supportedWhiteBalance += ",";
317            addComma = true;
318            switch (availableWhiteBalanceModes.data.u8[i]) {
319            case ANDROID_CONTROL_AWB_MODE_AUTO:
320                supportedWhiteBalance +=
321                    CameraParameters::WHITE_BALANCE_AUTO;
322                break;
323            case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
324                supportedWhiteBalance +=
325                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
326                break;
327            case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
328                supportedWhiteBalance +=
329                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
330                break;
331            case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
332                supportedWhiteBalance +=
333                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
334                break;
335            case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
336                supportedWhiteBalance +=
337                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
338                break;
339            case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
340                supportedWhiteBalance +=
341                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
342                break;
343            case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
344                supportedWhiteBalance +=
345                    CameraParameters::WHITE_BALANCE_TWILIGHT;
346                break;
347            case ANDROID_CONTROL_AWB_MODE_SHADE:
348                supportedWhiteBalance +=
349                    CameraParameters::WHITE_BALANCE_SHADE;
350                break;
351            // Skipping values not mappable to v1 API
352            case ANDROID_CONTROL_AWB_MODE_OFF:
353                addComma = false;
354                break;
355            default:
356                ALOGW("%s: Camera %d: Unknown white balance value: %d",
357                        __FUNCTION__, cameraId,
358                        availableWhiteBalanceModes.data.u8[i]);
359                addComma = false;
360                break;
361            }
362        }
363        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
364                supportedWhiteBalance);
365    }
366
367    effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
368    params.set(CameraParameters::KEY_EFFECT,
369            CameraParameters::EFFECT_NONE);
370
371    camera_metadata_ro_entry_t availableEffects =
372        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS, 0, 0, false);
373    if (!availableEffects.count) {
374        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS,
375                CameraParameters::EFFECT_NONE);
376    } else {
377        String8 supportedEffects;
378        bool addComma = false;
379        for (size_t i=0; i < availableEffects.count; i++) {
380            if (addComma) supportedEffects += ",";
381            addComma = true;
382            switch (availableEffects.data.u8[i]) {
383                case ANDROID_CONTROL_EFFECT_MODE_OFF:
384                    supportedEffects +=
385                        CameraParameters::EFFECT_NONE;
386                    break;
387                case ANDROID_CONTROL_EFFECT_MODE_MONO:
388                    supportedEffects +=
389                        CameraParameters::EFFECT_MONO;
390                    break;
391                case ANDROID_CONTROL_EFFECT_MODE_NEGATIVE:
392                    supportedEffects +=
393                        CameraParameters::EFFECT_NEGATIVE;
394                    break;
395                case ANDROID_CONTROL_EFFECT_MODE_SOLARIZE:
396                    supportedEffects +=
397                        CameraParameters::EFFECT_SOLARIZE;
398                    break;
399                case ANDROID_CONTROL_EFFECT_MODE_SEPIA:
400                    supportedEffects +=
401                        CameraParameters::EFFECT_SEPIA;
402                    break;
403                case ANDROID_CONTROL_EFFECT_MODE_POSTERIZE:
404                    supportedEffects +=
405                        CameraParameters::EFFECT_POSTERIZE;
406                    break;
407                case ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD:
408                    supportedEffects +=
409                        CameraParameters::EFFECT_WHITEBOARD;
410                    break;
411                case ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD:
412                    supportedEffects +=
413                        CameraParameters::EFFECT_BLACKBOARD;
414                    break;
415                case ANDROID_CONTROL_EFFECT_MODE_AQUA:
416                    supportedEffects +=
417                        CameraParameters::EFFECT_AQUA;
418                    break;
419                default:
420                    ALOGW("%s: Camera %d: Unknown effect value: %d",
421                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
422                    addComma = false;
423                    break;
424            }
425        }
426        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
427    }
428
429    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
430    params.set(CameraParameters::KEY_ANTIBANDING,
431            CameraParameters::ANTIBANDING_AUTO);
432
433    camera_metadata_ro_entry_t availableAntibandingModes =
434        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, 0, 0, false);
435    if (!availableAntibandingModes.count) {
436        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
437                CameraParameters::ANTIBANDING_OFF);
438    } else {
439        String8 supportedAntibanding;
440        bool addComma = false;
441        for (size_t i=0; i < availableAntibandingModes.count; i++) {
442            if (addComma) supportedAntibanding += ",";
443            addComma = true;
444            switch (availableAntibandingModes.data.u8[i]) {
445                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF:
446                    supportedAntibanding +=
447                        CameraParameters::ANTIBANDING_OFF;
448                    break;
449                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ:
450                    supportedAntibanding +=
451                        CameraParameters::ANTIBANDING_50HZ;
452                    break;
453                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ:
454                    supportedAntibanding +=
455                        CameraParameters::ANTIBANDING_60HZ;
456                    break;
457                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO:
458                    supportedAntibanding +=
459                        CameraParameters::ANTIBANDING_AUTO;
460                    break;
461                default:
462                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
463                        __FUNCTION__, cameraId,
464                            availableAntibandingModes.data.u8[i]);
465                    addComma = false;
466                    break;
467            }
468        }
469        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
470                supportedAntibanding);
471    }
472
473    sceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
474    params.set(CameraParameters::KEY_SCENE_MODE,
475            CameraParameters::SCENE_MODE_AUTO);
476
477    camera_metadata_ro_entry_t availableSceneModes =
478        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, 0, 0, false);
479    if (!availableSceneModes.count) {
480        params.remove(CameraParameters::KEY_SCENE_MODE);
481    } else {
482        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
483        bool addComma = true;
484        bool noSceneModes = false;
485        for (size_t i=0; i < availableSceneModes.count; i++) {
486            if (addComma) supportedSceneModes += ",";
487            addComma = true;
488            switch (availableSceneModes.data.u8[i]) {
489                case ANDROID_CONTROL_SCENE_MODE_DISABLED:
490                    noSceneModes = true;
491                    break;
492                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
493                    // Not in old API
494                    addComma = false;
495                    break;
496                case ANDROID_CONTROL_SCENE_MODE_ACTION:
497                    supportedSceneModes +=
498                        CameraParameters::SCENE_MODE_ACTION;
499                    break;
500                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
501                    supportedSceneModes +=
502                        CameraParameters::SCENE_MODE_PORTRAIT;
503                    break;
504                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
505                    supportedSceneModes +=
506                        CameraParameters::SCENE_MODE_LANDSCAPE;
507                    break;
508                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
509                    supportedSceneModes +=
510                        CameraParameters::SCENE_MODE_NIGHT;
511                    break;
512                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
513                    supportedSceneModes +=
514                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
515                    break;
516                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
517                    supportedSceneModes +=
518                        CameraParameters::SCENE_MODE_THEATRE;
519                    break;
520                case ANDROID_CONTROL_SCENE_MODE_BEACH:
521                    supportedSceneModes +=
522                        CameraParameters::SCENE_MODE_BEACH;
523                    break;
524                case ANDROID_CONTROL_SCENE_MODE_SNOW:
525                    supportedSceneModes +=
526                        CameraParameters::SCENE_MODE_SNOW;
527                    break;
528                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
529                    supportedSceneModes +=
530                        CameraParameters::SCENE_MODE_SUNSET;
531                    break;
532                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
533                    supportedSceneModes +=
534                        CameraParameters::SCENE_MODE_STEADYPHOTO;
535                    break;
536                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
537                    supportedSceneModes +=
538                        CameraParameters::SCENE_MODE_FIREWORKS;
539                    break;
540                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
541                    supportedSceneModes +=
542                        CameraParameters::SCENE_MODE_SPORTS;
543                    break;
544                case ANDROID_CONTROL_SCENE_MODE_PARTY:
545                    supportedSceneModes +=
546                        CameraParameters::SCENE_MODE_PARTY;
547                    break;
548                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
549                    supportedSceneModes +=
550                        CameraParameters::SCENE_MODE_CANDLELIGHT;
551                    break;
552                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
553                    supportedSceneModes +=
554                        CameraParameters::SCENE_MODE_BARCODE;
555                    break;
556                default:
557                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
558                        __FUNCTION__, cameraId,
559                            availableSceneModes.data.u8[i]);
560                    addComma = false;
561                    break;
562            }
563        }
564        if (!noSceneModes) {
565            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
566                    supportedSceneModes);
567        } else {
568            params.remove(CameraParameters::KEY_SCENE_MODE);
569        }
570    }
571
572    bool isFlashAvailable = false;
573    camera_metadata_ro_entry_t flashAvailable =
574        staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 0, 1, false);
575    if (flashAvailable.count) {
576        isFlashAvailable = flashAvailable.data.u8[0];
577    }
578
579    camera_metadata_ro_entry_t availableAeModes =
580        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES, 0, 0, false);
581
582    if (isFlashAvailable) {
583        flashMode = Parameters::FLASH_MODE_OFF;
584        params.set(CameraParameters::KEY_FLASH_MODE,
585                CameraParameters::FLASH_MODE_OFF);
586
587        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
588        supportedFlashModes = supportedFlashModes +
589            "," + CameraParameters::FLASH_MODE_AUTO +
590            "," + CameraParameters::FLASH_MODE_ON +
591            "," + CameraParameters::FLASH_MODE_TORCH;
592        for (size_t i=0; i < availableAeModes.count; i++) {
593            if (availableAeModes.data.u8[i] ==
594                    ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
595                supportedFlashModes = supportedFlashModes + "," +
596                    CameraParameters::FLASH_MODE_RED_EYE;
597                break;
598            }
599        }
600        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
601                supportedFlashModes);
602    } else {
603        flashMode = Parameters::FLASH_MODE_OFF;
604        params.set(CameraParameters::KEY_FLASH_MODE,
605                CameraParameters::FLASH_MODE_OFF);
606        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
607                CameraParameters::FLASH_MODE_OFF);
608    }
609
610    camera_metadata_ro_entry_t minFocusDistance =
611        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 1, false);
612
613    camera_metadata_ro_entry_t availableAfModes =
614        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES, 0, 0, false);
615
616    if (!minFocusDistance.count || minFocusDistance.data.f[0] == 0) {
617        // Fixed-focus lens
618        focusMode = Parameters::FOCUS_MODE_FIXED;
619        params.set(CameraParameters::KEY_FOCUS_MODE,
620                CameraParameters::FOCUS_MODE_FIXED);
621        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
622                CameraParameters::FOCUS_MODE_FIXED);
623    } else {
624        focusMode = Parameters::FOCUS_MODE_AUTO;
625        params.set(CameraParameters::KEY_FOCUS_MODE,
626                CameraParameters::FOCUS_MODE_AUTO);
627        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
628        bool addComma = true;
629
630        for (size_t i=0; i < availableAfModes.count; i++) {
631            if (addComma) supportedFocusModes += ",";
632            addComma = true;
633            switch (availableAfModes.data.u8[i]) {
634                case ANDROID_CONTROL_AF_MODE_AUTO:
635                    supportedFocusModes +=
636                        CameraParameters::FOCUS_MODE_AUTO;
637                    break;
638                case ANDROID_CONTROL_AF_MODE_MACRO:
639                    supportedFocusModes +=
640                        CameraParameters::FOCUS_MODE_MACRO;
641                    break;
642                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
643                    supportedFocusModes +=
644                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
645                    break;
646                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
647                    supportedFocusModes +=
648                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
649                    break;
650                case ANDROID_CONTROL_AF_MODE_EDOF:
651                    supportedFocusModes +=
652                        CameraParameters::FOCUS_MODE_EDOF;
653                    break;
654                // Not supported in old API
655                case ANDROID_CONTROL_AF_MODE_OFF:
656                    addComma = false;
657                    break;
658                default:
659                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
660                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
661                    addComma = false;
662                    break;
663            }
664        }
665        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
666                supportedFocusModes);
667    }
668    focusState = ANDROID_CONTROL_AF_STATE_INACTIVE;
669    shadowFocusMode = FOCUS_MODE_INVALID;
670
671    camera_metadata_ro_entry_t max3aRegions = staticInfo(ANDROID_CONTROL_MAX_REGIONS,
672            Parameters::NUM_REGION, Parameters::NUM_REGION);
673    if (max3aRegions.count != Parameters::NUM_REGION) return NO_INIT;
674
675    int32_t maxNumFocusAreas = 0;
676    if (focusMode != Parameters::FOCUS_MODE_FIXED) {
677        maxNumFocusAreas = max3aRegions.data.i32[Parameters::REGION_AF];
678    }
679    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, maxNumFocusAreas);
680    params.set(CameraParameters::KEY_FOCUS_AREAS,
681            "(0,0,0,0,0)");
682    focusingAreas.clear();
683    focusingAreas.add(Parameters::Area(0,0,0,0,0));
684
685    camera_metadata_ro_entry_t availableFocalLengths =
686        staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
687    if (!availableFocalLengths.count) return NO_INIT;
688
689    float minFocalLength = availableFocalLengths.data.f[0];
690    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
691
692    float horizFov, vertFov;
693    res = calculatePictureFovs(&horizFov, &vertFov);
694    if (res != OK) {
695        ALOGE("%s: Can't calculate field of views!", __FUNCTION__);
696        return res;
697    }
698
699    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
700    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
701
702    exposureCompensation = 0;
703    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
704                exposureCompensation);
705
706    camera_metadata_ro_entry_t exposureCompensationRange =
707        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE, 2, 2);
708    if (!exposureCompensationRange.count) return NO_INIT;
709
710    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
711            exposureCompensationRange.data.i32[1]);
712    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
713            exposureCompensationRange.data.i32[0]);
714
715    camera_metadata_ro_entry_t exposureCompensationStep =
716        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_STEP, 1, 1);
717    if (!exposureCompensationStep.count) return NO_INIT;
718
719    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
720            (float)exposureCompensationStep.data.r[0].numerator /
721            exposureCompensationStep.data.r[0].denominator);
722
723    autoExposureLock = false;
724    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
725            CameraParameters::FALSE);
726    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
727            CameraParameters::TRUE);
728
729    autoWhiteBalanceLock = false;
730    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
731            CameraParameters::FALSE);
732    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
733            CameraParameters::TRUE);
734
735    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
736    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
737            max3aRegions.data.i32[Parameters::REGION_AE]);
738    params.set(CameraParameters::KEY_METERING_AREAS,
739            "(0,0,0,0,0)");
740
741    zoom = 0;
742    params.set(CameraParameters::KEY_ZOOM, zoom);
743    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
744
745    camera_metadata_ro_entry_t maxDigitalZoom =
746        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, /*minCount*/1, /*maxCount*/1);
747    if (!maxDigitalZoom.count) return NO_INIT;
748
749    {
750        String8 zoomRatios;
751        float zoom = 1.f;
752        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
753                (NUM_ZOOM_STEPS-1);
754        bool addComma = false;
755        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
756            if (addComma) zoomRatios += ",";
757            addComma = true;
758            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
759            zoom += zoomIncrement;
760        }
761        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
762    }
763
764    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
765            CameraParameters::TRUE);
766    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
767            CameraParameters::FALSE);
768
769    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
770            "Infinity,Infinity,Infinity");
771
772    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
773            fastInfo.maxFaces);
774    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
775            0);
776
777    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
778            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
779
780    recordingHint = false;
781    params.set(CameraParameters::KEY_RECORDING_HINT,
782            CameraParameters::FALSE);
783
784    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
785            CameraParameters::TRUE);
786
787    videoStabilization = false;
788    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
789            CameraParameters::FALSE);
790
791    camera_metadata_ro_entry_t availableVideoStabilizationModes =
792        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 0, 0,
793                false);
794
795    if (availableVideoStabilizationModes.count > 1) {
796        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
797                CameraParameters::TRUE);
798    } else {
799        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
800                CameraParameters::FALSE);
801    }
802
803    // Set up initial state for non-Camera.Parameters state variables
804
805    storeMetadataInBuffers = true;
806    playShutterSound = true;
807    enableFaceDetect = false;
808
809    enableFocusMoveMessages = false;
810    afTriggerCounter = 1;
811    afStateCounter = 0;
812    currentAfTriggerId = -1;
813    afInMotion = false;
814
815    precaptureTriggerCounter = 1;
816
817    takePictureCounter = 0;
818
819    previewCallbackFlags = 0;
820    previewCallbackOneShot = false;
821    previewCallbackSurface = false;
822
823    char value[PROPERTY_VALUE_MAX];
824    property_get("camera.disable_zsl_mode", value, "0");
825    if (!strcmp(value,"1")) {
826        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
827        zslMode = false;
828    } else {
829        zslMode = true;
830    }
831
832    lightFx = LIGHTFX_NONE;
833
834    state = STOPPED;
835
836    paramsFlattened = params.flatten();
837
838    return OK;
839}
840
841String8 Parameters::get() const {
842    return paramsFlattened;
843}
844
845status_t Parameters::buildFastInfo() {
846
847    camera_metadata_ro_entry_t activeArraySize =
848        staticInfo(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 2, 4);
849    if (!activeArraySize.count) return NO_INIT;
850    int32_t arrayWidth;
851    int32_t arrayHeight;
852    if (activeArraySize.count == 2) {
853        ALOGW("%s: Camera %d: activeArraySize is missing xmin/ymin!",
854                __FUNCTION__, cameraId);
855        arrayWidth = activeArraySize.data.i32[0];
856        arrayHeight = activeArraySize.data.i32[1];
857    } else if (activeArraySize.count == 4) {
858        arrayWidth = activeArraySize.data.i32[2];
859        arrayHeight = activeArraySize.data.i32[3];
860    } else return NO_INIT;
861
862    // We'll set the target FPS range for still captures to be as wide
863    // as possible to give the HAL maximum latitude for exposure selection
864    camera_metadata_ro_entry_t availableFpsRanges =
865        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
866    if (availableFpsRanges.count < 2 || availableFpsRanges.count % 2 != 0) {
867        return NO_INIT;
868    }
869
870    int32_t bestStillCaptureFpsRange[2] = {
871        availableFpsRanges.data.i32[0], availableFpsRanges.data.i32[1]
872    };
873    int32_t curRange =
874            bestStillCaptureFpsRange[1] - bestStillCaptureFpsRange[0];
875    for (size_t i = 2; i < availableFpsRanges.count; i += 2) {
876        int32_t nextRange =
877                availableFpsRanges.data.i32[i + 1] -
878                availableFpsRanges.data.i32[i];
879        if ( (nextRange > curRange) ||       // Maximize size of FPS range first
880                (nextRange == curRange &&    // Then minimize low-end FPS
881                 bestStillCaptureFpsRange[0] > availableFpsRanges.data.i32[i])) {
882
883            bestStillCaptureFpsRange[0] = availableFpsRanges.data.i32[i];
884            bestStillCaptureFpsRange[1] = availableFpsRanges.data.i32[i + 1];
885            curRange = nextRange;
886        }
887    }
888
889    camera_metadata_ro_entry_t availableFaceDetectModes =
890        staticInfo(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, 0, 0,
891                false);
892
893    uint8_t bestFaceDetectMode =
894        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
895    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
896        switch (availableFaceDetectModes.data.u8[i]) {
897            case ANDROID_STATISTICS_FACE_DETECT_MODE_OFF:
898                break;
899            case ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE:
900                if (bestFaceDetectMode !=
901                        ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
902                    bestFaceDetectMode =
903                        ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE;
904                }
905                break;
906            case ANDROID_STATISTICS_FACE_DETECT_MODE_FULL:
907                bestFaceDetectMode =
908                    ANDROID_STATISTICS_FACE_DETECT_MODE_FULL;
909                break;
910            default:
911                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
912                        __FUNCTION__, cameraId,
913                        availableFaceDetectModes.data.u8[i]);
914                return NO_INIT;
915        }
916    }
917
918    int32_t maxFaces = 0;
919    camera_metadata_ro_entry_t maxFacesDetected =
920        staticInfo(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 0, 1, false);
921    if (maxFacesDetected.count) {
922        maxFaces = maxFacesDetected.data.i32[0];
923    }
924
925    camera_metadata_ro_entry_t availableSceneModes =
926        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, 0, 0, false);
927    camera_metadata_ro_entry_t sceneModeOverrides =
928        staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES, 0, 0, false);
929    camera_metadata_ro_entry_t minFocusDistance =
930        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 0, false);
931    bool fixedLens = minFocusDistance.count == 0 ||
932        minFocusDistance.data.f[0] == 0;
933
934    camera_metadata_ro_entry_t availableFocalLengths =
935        staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
936    if (!availableFocalLengths.count) return NO_INIT;
937
938    camera_metadata_ro_entry_t availableFormats =
939        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
940    if (!availableFormats.count) return NO_INIT;
941
942
943    if (sceneModeOverrides.count > 0) {
944        // sceneModeOverrides is defined to have 3 entries for each scene mode,
945        // which are AE, AWB, and AF override modes the HAL wants for that scene
946        // mode.
947        const size_t kModesPerSceneMode = 3;
948        if (sceneModeOverrides.count !=
949                availableSceneModes.count * kModesPerSceneMode) {
950            ALOGE("%s: Camera %d: Scene mode override list is an "
951                    "unexpected size: %d (expected %d)", __FUNCTION__,
952                    cameraId, sceneModeOverrides.count,
953                    availableSceneModes.count);
954            return NO_INIT;
955        }
956        for (size_t i = 0; i < availableSceneModes.count; i++) {
957            DeviceInfo::OverrideModes modes;
958            uint8_t aeMode =
959                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
960            switch(aeMode) {
961                case ANDROID_CONTROL_AE_MODE_ON:
962                    modes.flashMode = FLASH_MODE_OFF;
963                    break;
964                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
965                    modes.flashMode = FLASH_MODE_AUTO;
966                    break;
967                case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
968                    modes.flashMode = FLASH_MODE_ON;
969                    break;
970                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
971                    modes.flashMode = FLASH_MODE_RED_EYE;
972                    break;
973                default:
974                    ALOGE("%s: Unknown override AE mode: %d", __FUNCTION__,
975                            aeMode);
976                    modes.flashMode = FLASH_MODE_INVALID;
977                    break;
978            }
979            modes.wbMode =
980                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 1];
981            uint8_t afMode =
982                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
983            switch(afMode) {
984                case ANDROID_CONTROL_AF_MODE_OFF:
985                    modes.focusMode = fixedLens ?
986                            FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
987                    break;
988                case ANDROID_CONTROL_AF_MODE_AUTO:
989                case ANDROID_CONTROL_AF_MODE_MACRO:
990                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
991                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
992                case ANDROID_CONTROL_AF_MODE_EDOF:
993                    modes.focusMode = static_cast<focusMode_t>(afMode);
994                    break;
995                default:
996                    ALOGE("%s: Unknown override AF mode: %d", __FUNCTION__,
997                            afMode);
998                    modes.focusMode = FOCUS_MODE_INVALID;
999                    break;
1000            }
1001            fastInfo.sceneModeOverrides.add(availableSceneModes.data.u8[i],
1002                    modes);
1003        }
1004    }
1005
1006    fastInfo.arrayWidth = arrayWidth;
1007    fastInfo.arrayHeight = arrayHeight;
1008    fastInfo.bestStillCaptureFpsRange[0] = bestStillCaptureFpsRange[0];
1009    fastInfo.bestStillCaptureFpsRange[1] = bestStillCaptureFpsRange[1];
1010    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
1011    fastInfo.maxFaces = maxFaces;
1012
1013    // Find smallest (widest-angle) focal length to use as basis of still
1014    // picture FOV reporting.
1015    fastInfo.minFocalLength = availableFocalLengths.data.f[0];
1016    for (size_t i = 1; i < availableFocalLengths.count; i++) {
1017        if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
1018            fastInfo.minFocalLength = availableFocalLengths.data.f[i];
1019        }
1020    }
1021
1022    // Check if the HAL supports HAL_PIXEL_FORMAT_YCbCr_420_888
1023    fastInfo.useFlexibleYuv = false;
1024    for (size_t i = 0; i < availableFormats.count; i++) {
1025        if (availableFormats.data.i32[i] == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1026            fastInfo.useFlexibleYuv = true;
1027            break;
1028        }
1029    }
1030    ALOGV("Camera %d: Flexible YUV %s supported",
1031            cameraId, fastInfo.useFlexibleYuv ? "is" : "is not");
1032
1033    return OK;
1034}
1035
1036status_t Parameters::buildQuirks() {
1037    camera_metadata_ro_entry_t entry;
1038    entry = info->find(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO);
1039    quirks.triggerAfWithAuto = (entry.count != 0 && entry.data.u8[0] == 1);
1040    ALOGV_IF(quirks.triggerAfWithAuto, "Camera %d: Quirk triggerAfWithAuto enabled",
1041            cameraId);
1042
1043    entry = info->find(ANDROID_QUIRKS_USE_ZSL_FORMAT);
1044    quirks.useZslFormat = (entry.count != 0 && entry.data.u8[0] == 1);
1045    ALOGV_IF(quirks.useZslFormat, "Camera %d: Quirk useZslFormat enabled",
1046            cameraId);
1047
1048    entry = info->find(ANDROID_QUIRKS_METERING_CROP_REGION);
1049    quirks.meteringCropRegion = (entry.count != 0 && entry.data.u8[0] == 1);
1050    ALOGV_IF(quirks.meteringCropRegion, "Camera %d: Quirk meteringCropRegion"
1051                " enabled", cameraId);
1052
1053    entry = info->find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
1054    quirks.partialResults = (entry.count != 0 && entry.data.u8[0] == 1);
1055    ALOGV_IF(quirks.partialResults, "Camera %d: Quirk usePartialResult"
1056                " enabled", cameraId);
1057
1058    return OK;
1059}
1060
1061camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
1062        size_t minCount, size_t maxCount, bool required) const {
1063    camera_metadata_ro_entry_t entry = info->find(tag);
1064
1065    if (CC_UNLIKELY( entry.count == 0 ) && required) {
1066        const char* tagSection = get_camera_metadata_section_name(tag);
1067        if (tagSection == NULL) tagSection = "<unknown>";
1068        const char* tagName = get_camera_metadata_tag_name(tag);
1069        if (tagName == NULL) tagName = "<unknown>";
1070
1071        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
1072                tagSection, tagName, tag);
1073    } else if (CC_UNLIKELY(
1074            (minCount != 0 && entry.count < minCount) ||
1075            (maxCount != 0 && entry.count > maxCount) ) ) {
1076        const char* tagSection = get_camera_metadata_section_name(tag);
1077        if (tagSection == NULL) tagSection = "<unknown>";
1078        const char* tagName = get_camera_metadata_tag_name(tag);
1079        if (tagName == NULL) tagName = "<unknown>";
1080        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1081                "Expected between %d and %d values, but got %d values",
1082                tagSection, tagName, tag, minCount, maxCount, entry.count);
1083    }
1084
1085    return entry;
1086}
1087
1088status_t Parameters::set(const String8& paramString) {
1089    status_t res;
1090
1091    CameraParameters newParams(paramString);
1092
1093    // TODO: Currently ignoring any changes to supposedly read-only parameters
1094    // such as supported preview sizes, etc. Should probably produce an error if
1095    // they're changed.
1096
1097    /** Extract and verify new parameters */
1098
1099    size_t i;
1100
1101    Parameters validatedParams(*this);
1102
1103    // PREVIEW_SIZE
1104    newParams.getPreviewSize(&validatedParams.previewWidth,
1105            &validatedParams.previewHeight);
1106
1107    if (validatedParams.previewWidth != previewWidth ||
1108            validatedParams.previewHeight != previewHeight) {
1109        if (state >= PREVIEW) {
1110            ALOGE("%s: Preview size cannot be updated when preview "
1111                    "is active! (Currently %d x %d, requested %d x %d",
1112                    __FUNCTION__,
1113                    previewWidth, previewHeight,
1114                    validatedParams.previewWidth, validatedParams.previewHeight);
1115            return BAD_VALUE;
1116        }
1117        for (i = 0; i < availablePreviewSizes.size(); i++) {
1118            if ((availablePreviewSizes[i].width ==
1119                    validatedParams.previewWidth) &&
1120                (availablePreviewSizes[i].height ==
1121                    validatedParams.previewHeight)) break;
1122        }
1123        if (i == availablePreviewSizes.size()) {
1124            ALOGE("%s: Requested preview size %d x %d is not supported",
1125                    __FUNCTION__, validatedParams.previewWidth,
1126                    validatedParams.previewHeight);
1127            return BAD_VALUE;
1128        }
1129    }
1130
1131    // RECORDING_HINT (always supported)
1132    validatedParams.recordingHint = boolFromString(
1133        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1134    IF_ALOGV() { // Avoid unused variable warning
1135        bool recordingHintChanged =
1136                validatedParams.recordingHint != recordingHint;
1137        if (recordingHintChanged) {
1138            ALOGV("%s: Recording hint changed to %d",
1139                  __FUNCTION__, validatedParams.recordingHint);
1140        }
1141    }
1142
1143    // PREVIEW_FPS_RANGE
1144
1145    /**
1146     * Use the single FPS value if it was set later than the range.
1147     * Otherwise, use the range value.
1148     */
1149    bool fpsUseSingleValue;
1150    {
1151        const char *fpsRange, *fpsSingle;
1152
1153        fpsRange = params.get(CameraParameters::KEY_PREVIEW_FRAME_RATE);
1154        fpsSingle = params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
1155
1156        /**
1157         * Pick either the range or the single key if only one was set.
1158         *
1159         * If both are set, pick the one that has greater set order.
1160         */
1161        if (fpsRange == NULL && fpsSingle == NULL) {
1162            ALOGE("%s: FPS was not set. One of %s or %s must be set.",
1163                  __FUNCTION__, CameraParameters::KEY_PREVIEW_FRAME_RATE,
1164                  CameraParameters::KEY_PREVIEW_FPS_RANGE);
1165            return BAD_VALUE;
1166        } else if (fpsRange == NULL) {
1167            fpsUseSingleValue = true;
1168            ALOGV("%s: FPS range not set, using FPS single value",
1169                  __FUNCTION__);
1170        } else if (fpsSingle == NULL) {
1171            fpsUseSingleValue = false;
1172            ALOGV("%s: FPS single not set, using FPS range value",
1173                  __FUNCTION__);
1174        } else {
1175            int fpsKeyOrder;
1176            res = params.compareSetOrder(
1177                    CameraParameters::KEY_PREVIEW_FRAME_RATE,
1178                    CameraParameters::KEY_PREVIEW_FPS_RANGE,
1179                    &fpsKeyOrder);
1180            LOG_ALWAYS_FATAL_IF(res != OK, "Impossibly bad FPS keys");
1181
1182            fpsUseSingleValue = (fpsKeyOrder > 0);
1183
1184        }
1185
1186        ALOGV("%s: Preview FPS value is used from '%s'",
1187              __FUNCTION__, fpsUseSingleValue ? "single" : "range");
1188    }
1189    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
1190            &validatedParams.previewFpsRange[1]);
1191    validatedParams.previewFpsRange[0] /= kFpsToApiScale;
1192    validatedParams.previewFpsRange[1] /= kFpsToApiScale;
1193
1194    // Ignore the FPS range if the FPS single has higher precedence
1195    if (!fpsUseSingleValue) {
1196        ALOGV("%s: Preview FPS range (%d, %d)", __FUNCTION__,
1197                validatedParams.previewFpsRange[0],
1198                validatedParams.previewFpsRange[1]);
1199
1200        camera_metadata_ro_entry_t availablePreviewFpsRanges =
1201            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1202        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1203            if ((availablePreviewFpsRanges.data.i32[i] ==
1204                    validatedParams.previewFpsRange[0]) &&
1205                (availablePreviewFpsRanges.data.i32[i+1] ==
1206                    validatedParams.previewFpsRange[1]) ) {
1207                break;
1208            }
1209        }
1210        if (i == availablePreviewFpsRanges.count) {
1211            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
1212                __FUNCTION__, validatedParams.previewFpsRange[0],
1213                    validatedParams.previewFpsRange[1]);
1214            return BAD_VALUE;
1215        }
1216    }
1217
1218    // PREVIEW_FORMAT
1219    validatedParams.previewFormat =
1220            formatStringToEnum(newParams.getPreviewFormat());
1221    if (validatedParams.previewFormat != previewFormat) {
1222        if (state >= PREVIEW) {
1223            ALOGE("%s: Preview format cannot be updated when preview "
1224                    "is active!", __FUNCTION__);
1225            return BAD_VALUE;
1226        }
1227        camera_metadata_ro_entry_t availableFormats =
1228            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1229        // If using flexible YUV, always support NV21/YV12. Otherwise, check
1230        // HAL's list.
1231        if (! (fastInfo.useFlexibleYuv &&
1232                (validatedParams.previewFormat ==
1233                        HAL_PIXEL_FORMAT_YCrCb_420_SP ||
1234                 validatedParams.previewFormat ==
1235                        HAL_PIXEL_FORMAT_YV12) ) ) {
1236            // Not using flexible YUV format, so check explicitly
1237            for (i = 0; i < availableFormats.count; i++) {
1238                if (availableFormats.data.i32[i] ==
1239                        validatedParams.previewFormat) break;
1240            }
1241            if (i == availableFormats.count) {
1242                ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1243                        __FUNCTION__, newParams.getPreviewFormat(),
1244                        validatedParams.previewFormat);
1245                return BAD_VALUE;
1246            }
1247        }
1248    }
1249
1250    // PREVIEW_FRAME_RATE Deprecated
1251    // - Use only if the single FPS value was set later than the FPS range
1252    if (fpsUseSingleValue) {
1253        int previewFps = newParams.getPreviewFrameRate();
1254        ALOGV("%s: Preview FPS single value requested: %d",
1255              __FUNCTION__, previewFps);
1256        {
1257            camera_metadata_ro_entry_t availableFrameRates =
1258                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1259            /**
1260              * If recording hint is set, find the range that encompasses
1261              * previewFps with the largest min index.
1262              *
1263              * If recording hint is not set, find the range with previewFps
1264              * with the smallest min index.
1265              *
1266              * Either way, in case of multiple ranges, break the tie by
1267              * selecting the smaller range.
1268              */
1269
1270            // all ranges which have previewFps
1271            Vector<Range> candidateRanges;
1272            for (i = 0; i < availableFrameRates.count; i+=2) {
1273                Range r = {
1274                            availableFrameRates.data.i32[i],
1275                            availableFrameRates.data.i32[i+1]
1276                };
1277
1278                if (r.min <= previewFps && previewFps <= r.max) {
1279                    candidateRanges.push(r);
1280                }
1281            }
1282            if (candidateRanges.isEmpty()) {
1283                ALOGE("%s: Requested preview frame rate %d is not supported",
1284                        __FUNCTION__, previewFps);
1285                return BAD_VALUE;
1286            }
1287            // most applicable range with targetFps
1288            Range bestRange = candidateRanges[0];
1289            for (i = 1; i < candidateRanges.size(); ++i) {
1290                Range r = candidateRanges[i];
1291
1292                // Find by largest minIndex in recording mode
1293                if (validatedParams.recordingHint) {
1294                    if (r.min > bestRange.min) {
1295                        bestRange = r;
1296                    }
1297                    else if (r.min == bestRange.min && r.max < bestRange.max) {
1298                        bestRange = r;
1299                    }
1300                }
1301                // Find by smallest minIndex in preview mode
1302                else {
1303                    if (r.min < bestRange.min) {
1304                        bestRange = r;
1305                    }
1306                    else if (r.min == bestRange.min && r.max < bestRange.max) {
1307                        bestRange = r;
1308                    }
1309                }
1310            }
1311
1312            validatedParams.previewFpsRange[0] =
1313                    bestRange.min;
1314            validatedParams.previewFpsRange[1] =
1315                    bestRange.max;
1316
1317            ALOGV("%s: New preview FPS range: %d, %d, recordingHint = %d",
1318                __FUNCTION__,
1319                validatedParams.previewFpsRange[0],
1320                validatedParams.previewFpsRange[1],
1321                validatedParams.recordingHint);
1322        }
1323    }
1324
1325    /**
1326     * Update Preview FPS and Preview FPS ranges based on
1327     * what we actually set.
1328     *
1329     * This updates the API-visible (Camera.Parameters#getParameters) values of
1330     * the FPS fields, not only the internal versions.
1331     *
1332     * Order matters: The value that was set last takes precedence.
1333     * - If the client does a setParameters(getParameters()) we retain
1334     *   the same order for preview FPS.
1335     */
1336    if (!fpsUseSingleValue) {
1337        // Set fps single, then fps range (range wins)
1338        validatedParams.params.setPreviewFrameRate(
1339                fpsFromRange(/*min*/validatedParams.previewFpsRange[0],
1340                             /*max*/validatedParams.previewFpsRange[1]));
1341        validatedParams.params.setPreviewFpsRange(
1342                validatedParams.previewFpsRange[0],
1343                validatedParams.previewFpsRange[1]);
1344    } else {
1345        // Set fps range, then fps single (single wins)
1346        validatedParams.params.setPreviewFpsRange(
1347                validatedParams.previewFpsRange[0],
1348                validatedParams.previewFpsRange[1]);
1349        validatedParams.params.setPreviewFrameRate(
1350                fpsFromRange(/*min*/validatedParams.previewFpsRange[0],
1351                             /*max*/validatedParams.previewFpsRange[1]));
1352    }
1353
1354    // PICTURE_SIZE
1355    newParams.getPictureSize(&validatedParams.pictureWidth,
1356            &validatedParams.pictureHeight);
1357    if (validatedParams.pictureWidth == pictureWidth ||
1358            validatedParams.pictureHeight == pictureHeight) {
1359        camera_metadata_ro_entry_t availablePictureSizes =
1360            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1361        for (i = 0; i < availablePictureSizes.count; i+=2) {
1362            if ((availablePictureSizes.data.i32[i] ==
1363                    validatedParams.pictureWidth) &&
1364                (availablePictureSizes.data.i32[i+1] ==
1365                    validatedParams.pictureHeight)) break;
1366        }
1367        if (i == availablePictureSizes.count) {
1368            ALOGE("%s: Requested picture size %d x %d is not supported",
1369                    __FUNCTION__, validatedParams.pictureWidth,
1370                    validatedParams.pictureHeight);
1371            return BAD_VALUE;
1372        }
1373    }
1374
1375    // JPEG_THUMBNAIL_WIDTH/HEIGHT
1376    validatedParams.jpegThumbSize[0] =
1377            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1378    validatedParams.jpegThumbSize[1] =
1379            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1380    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
1381            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
1382        camera_metadata_ro_entry_t availableJpegThumbSizes =
1383            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1384        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1385            if ((availableJpegThumbSizes.data.i32[i] ==
1386                    validatedParams.jpegThumbSize[0]) &&
1387                (availableJpegThumbSizes.data.i32[i+1] ==
1388                    validatedParams.jpegThumbSize[1])) break;
1389        }
1390        if (i == availableJpegThumbSizes.count) {
1391            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1392                    __FUNCTION__, validatedParams.jpegThumbSize[0],
1393                    validatedParams.jpegThumbSize[1]);
1394            return BAD_VALUE;
1395        }
1396    }
1397
1398    // JPEG_THUMBNAIL_QUALITY
1399    int quality = newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1400    // also makes sure quality fits in uint8_t
1401    if (quality < 0 || quality > 100) {
1402        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1403                __FUNCTION__, quality);
1404        return BAD_VALUE;
1405    }
1406    validatedParams.jpegThumbQuality = quality;
1407
1408    // JPEG_QUALITY
1409    quality = newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1410    // also makes sure quality fits in uint8_t
1411    if (quality < 0 || quality > 100) {
1412        ALOGE("%s: Requested JPEG quality %d is not supported",
1413                __FUNCTION__, quality);
1414        return BAD_VALUE;
1415    }
1416    validatedParams.jpegQuality = quality;
1417
1418    // ROTATION
1419    validatedParams.jpegRotation =
1420            newParams.getInt(CameraParameters::KEY_ROTATION);
1421    if (validatedParams.jpegRotation != 0 &&
1422            validatedParams.jpegRotation != 90 &&
1423            validatedParams.jpegRotation != 180 &&
1424            validatedParams.jpegRotation != 270) {
1425        ALOGE("%s: Requested picture rotation angle %d is not supported",
1426                __FUNCTION__, validatedParams.jpegRotation);
1427        return BAD_VALUE;
1428    }
1429
1430    // GPS
1431
1432    const char *gpsLatStr =
1433            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1434    if (gpsLatStr != NULL) {
1435        const char *gpsLongStr =
1436                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1437        const char *gpsAltitudeStr =
1438                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1439        const char *gpsTimeStr =
1440                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1441        const char *gpsProcMethodStr =
1442                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1443        if (gpsLongStr == NULL ||
1444                gpsAltitudeStr == NULL ||
1445                gpsTimeStr == NULL ||
1446                gpsProcMethodStr == NULL) {
1447            ALOGE("%s: Incomplete set of GPS parameters provided",
1448                    __FUNCTION__);
1449            return BAD_VALUE;
1450        }
1451        char *endPtr;
1452        errno = 0;
1453        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1454        if (errno || endPtr == gpsLatStr) {
1455            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1456            return BAD_VALUE;
1457        }
1458        errno = 0;
1459        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1460        if (errno || endPtr == gpsLongStr) {
1461            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1462            return BAD_VALUE;
1463        }
1464        errno = 0;
1465        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1466        if (errno || endPtr == gpsAltitudeStr) {
1467            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1468                    gpsAltitudeStr);
1469            return BAD_VALUE;
1470        }
1471        errno = 0;
1472        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1473        if (errno || endPtr == gpsTimeStr) {
1474            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1475            return BAD_VALUE;
1476        }
1477        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1478
1479        validatedParams.gpsEnabled = true;
1480    } else {
1481        validatedParams.gpsEnabled = false;
1482    }
1483
1484    // EFFECT
1485    validatedParams.effectMode = effectModeStringToEnum(
1486        newParams.get(CameraParameters::KEY_EFFECT) );
1487    if (validatedParams.effectMode != effectMode) {
1488        camera_metadata_ro_entry_t availableEffectModes =
1489            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1490        for (i = 0; i < availableEffectModes.count; i++) {
1491            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1492        }
1493        if (i == availableEffectModes.count) {
1494            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1495                    __FUNCTION__,
1496                    newParams.get(CameraParameters::KEY_EFFECT) );
1497            return BAD_VALUE;
1498        }
1499    }
1500
1501    // ANTIBANDING
1502    validatedParams.antibandingMode = abModeStringToEnum(
1503        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1504    if (validatedParams.antibandingMode != antibandingMode) {
1505        camera_metadata_ro_entry_t availableAbModes =
1506            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1507        for (i = 0; i < availableAbModes.count; i++) {
1508            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1509                break;
1510        }
1511        if (i == availableAbModes.count) {
1512            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1513                    __FUNCTION__,
1514                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1515            return BAD_VALUE;
1516        }
1517    }
1518
1519    // SCENE_MODE
1520    validatedParams.sceneMode = sceneModeStringToEnum(
1521        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1522    if (validatedParams.sceneMode != sceneMode &&
1523            validatedParams.sceneMode !=
1524            ANDROID_CONTROL_SCENE_MODE_DISABLED) {
1525        camera_metadata_ro_entry_t availableSceneModes =
1526            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1527        for (i = 0; i < availableSceneModes.count; i++) {
1528            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1529                break;
1530        }
1531        if (i == availableSceneModes.count) {
1532            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1533                    __FUNCTION__,
1534                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1535            return BAD_VALUE;
1536        }
1537    }
1538    bool sceneModeSet =
1539            validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_DISABLED;
1540
1541    // FLASH_MODE
1542    if (sceneModeSet) {
1543        validatedParams.flashMode =
1544                fastInfo.sceneModeOverrides.
1545                        valueFor(validatedParams.sceneMode).flashMode;
1546    } else {
1547        validatedParams.flashMode = FLASH_MODE_INVALID;
1548    }
1549    if (validatedParams.flashMode == FLASH_MODE_INVALID) {
1550        validatedParams.flashMode = flashModeStringToEnum(
1551            newParams.get(CameraParameters::KEY_FLASH_MODE) );
1552    }
1553
1554    if (validatedParams.flashMode != flashMode) {
1555        camera_metadata_ro_entry_t flashAvailable =
1556            staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 1, 1);
1557        if (!flashAvailable.data.u8[0] &&
1558                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1559            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1560                    "No flash on device", __FUNCTION__,
1561                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1562            return BAD_VALUE;
1563        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1564            camera_metadata_ro_entry_t availableAeModes =
1565                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1566            for (i = 0; i < availableAeModes.count; i++) {
1567                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1568                    break;
1569            }
1570            if (i == availableAeModes.count) {
1571                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1572                        __FUNCTION__,
1573                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1574                return BAD_VALUE;
1575            }
1576        } else if (validatedParams.flashMode == -1) {
1577            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1578                    __FUNCTION__,
1579                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1580            return BAD_VALUE;
1581        }
1582        // Update in case of override
1583        newParams.set(CameraParameters::KEY_FLASH_MODE,
1584                flashModeEnumToString(validatedParams.flashMode));
1585    }
1586
1587    // WHITE_BALANCE
1588    if (sceneModeSet) {
1589        validatedParams.wbMode =
1590                fastInfo.sceneModeOverrides.
1591                        valueFor(validatedParams.sceneMode).wbMode;
1592    } else {
1593        validatedParams.wbMode = ANDROID_CONTROL_AWB_MODE_OFF;
1594    }
1595    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_MODE_OFF) {
1596        validatedParams.wbMode = wbModeStringToEnum(
1597            newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1598    }
1599    if (validatedParams.wbMode != wbMode) {
1600        camera_metadata_ro_entry_t availableWbModes =
1601            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES, 0, 0, false);
1602        for (i = 0; i < availableWbModes.count; i++) {
1603            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1604        }
1605        if (i == availableWbModes.count) {
1606            ALOGE("%s: Requested white balance mode %s is not supported",
1607                    __FUNCTION__,
1608                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1609            return BAD_VALUE;
1610        }
1611        // Update in case of override
1612        newParams.set(CameraParameters::KEY_WHITE_BALANCE,
1613                wbModeEnumToString(validatedParams.wbMode));
1614    }
1615
1616    // FOCUS_MODE
1617    if (sceneModeSet) {
1618        validatedParams.focusMode =
1619                fastInfo.sceneModeOverrides.
1620                        valueFor(validatedParams.sceneMode).focusMode;
1621    } else {
1622        validatedParams.focusMode = FOCUS_MODE_INVALID;
1623    }
1624    if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
1625        validatedParams.focusMode = focusModeStringToEnum(
1626                newParams.get(CameraParameters::KEY_FOCUS_MODE) );
1627    }
1628    if (validatedParams.focusMode != focusMode) {
1629        validatedParams.currentAfTriggerId = -1;
1630        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1631            camera_metadata_ro_entry_t minFocusDistance =
1632                staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 0,
1633                        false);
1634            if (minFocusDistance.count && minFocusDistance.data.f[0] == 0) {
1635                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1636                        "fixed focus lens",
1637                        __FUNCTION__,
1638                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1639                return BAD_VALUE;
1640            } else if (validatedParams.focusMode !=
1641                    Parameters::FOCUS_MODE_INFINITY) {
1642                camera_metadata_ro_entry_t availableFocusModes =
1643                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1644                for (i = 0; i < availableFocusModes.count; i++) {
1645                    if (validatedParams.focusMode ==
1646                            availableFocusModes.data.u8[i]) break;
1647                }
1648                if (i == availableFocusModes.count) {
1649                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1650                            __FUNCTION__,
1651                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1652                    return BAD_VALUE;
1653                }
1654            }
1655        }
1656        validatedParams.focusState = ANDROID_CONTROL_AF_STATE_INACTIVE;
1657        // Always reset shadow focus mode to avoid reverting settings
1658        validatedParams.shadowFocusMode = FOCUS_MODE_INVALID;
1659        // Update in case of override
1660        newParams.set(CameraParameters::KEY_FOCUS_MODE,
1661                focusModeEnumToString(validatedParams.focusMode));
1662    } else {
1663        validatedParams.currentAfTriggerId = currentAfTriggerId;
1664    }
1665
1666    // FOCUS_AREAS
1667    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1668            &validatedParams.focusingAreas);
1669    size_t maxAfRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
1670              Parameters::NUM_REGION, Parameters::NUM_REGION).
1671              data.i32[Parameters::REGION_AF];
1672    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1673            maxAfRegions, AREA_KIND_FOCUS);
1674    if (res != OK) {
1675        ALOGE("%s: Requested focus areas are malformed: %s",
1676                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1677        return BAD_VALUE;
1678    }
1679
1680    // EXPOSURE_COMPENSATION
1681    validatedParams.exposureCompensation =
1682        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1683    camera_metadata_ro_entry_t exposureCompensationRange =
1684        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE);
1685    if ((validatedParams.exposureCompensation <
1686            exposureCompensationRange.data.i32[0]) ||
1687        (validatedParams.exposureCompensation >
1688            exposureCompensationRange.data.i32[1])) {
1689        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1690                __FUNCTION__, validatedParams.exposureCompensation);
1691        return BAD_VALUE;
1692    }
1693
1694    // AUTO_EXPOSURE_LOCK (always supported)
1695    validatedParams.autoExposureLock = boolFromString(
1696        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1697
1698    // AUTO_WHITEBALANCE_LOCK (always supported)
1699    validatedParams.autoWhiteBalanceLock = boolFromString(
1700        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1701
1702    // METERING_AREAS
1703    size_t maxAeRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
1704            Parameters::NUM_REGION, Parameters::NUM_REGION).
1705            data.i32[Parameters::REGION_AE];
1706    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1707            &validatedParams.meteringAreas);
1708    if (res == OK) {
1709        res = validateAreas(validatedParams.meteringAreas, maxAeRegions,
1710                            AREA_KIND_METERING);
1711    }
1712    if (res != OK) {
1713        ALOGE("%s: Requested metering areas are malformed: %s",
1714                __FUNCTION__,
1715                newParams.get(CameraParameters::KEY_METERING_AREAS));
1716        return BAD_VALUE;
1717    }
1718
1719    // ZOOM
1720    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1721    if (validatedParams.zoom < 0
1722                || validatedParams.zoom >= (int)NUM_ZOOM_STEPS) {
1723        ALOGE("%s: Requested zoom level %d is not supported",
1724                __FUNCTION__, validatedParams.zoom);
1725        return BAD_VALUE;
1726    }
1727
1728    // VIDEO_SIZE
1729    newParams.getVideoSize(&validatedParams.videoWidth,
1730            &validatedParams.videoHeight);
1731    if (validatedParams.videoWidth != videoWidth ||
1732            validatedParams.videoHeight != videoHeight) {
1733        if (state == RECORD) {
1734            ALOGE("%s: Video size cannot be updated when recording is active!",
1735                    __FUNCTION__);
1736            return BAD_VALUE;
1737        }
1738        for (i = 0; i < availablePreviewSizes.size(); i++) {
1739            if ((availablePreviewSizes[i].width ==
1740                    validatedParams.videoWidth) &&
1741                (availablePreviewSizes[i].height ==
1742                    validatedParams.videoHeight)) break;
1743        }
1744        if (i == availablePreviewSizes.size()) {
1745            ALOGE("%s: Requested video size %d x %d is not supported",
1746                    __FUNCTION__, validatedParams.videoWidth,
1747                    validatedParams.videoHeight);
1748            return BAD_VALUE;
1749        }
1750    }
1751
1752    // VIDEO_STABILIZATION
1753    validatedParams.videoStabilization = boolFromString(
1754        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1755    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1756        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 0, 0,
1757                false);
1758    if (validatedParams.videoStabilization &&
1759            availableVideoStabilizationModes.count == 1) {
1760        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1761    }
1762
1763    // LIGHTFX
1764    validatedParams.lightFx = lightFxStringToEnum(
1765        newParams.get(CameraParameters::KEY_LIGHTFX));
1766
1767    /** Update internal parameters */
1768
1769    *this = validatedParams;
1770
1771    /** Update external parameters calculated from the internal ones */
1772
1773    // HORIZONTAL/VERTICAL FIELD OF VIEW
1774    float horizFov, vertFov;
1775    res = calculatePictureFovs(&horizFov, &vertFov);
1776    if (res != OK) {
1777        ALOGE("%s: Can't calculate FOVs", __FUNCTION__);
1778        // continue so parameters are at least consistent
1779    }
1780    newParams.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
1781            horizFov);
1782    newParams.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE,
1783            vertFov);
1784    ALOGV("Current still picture FOV: %f x %f deg", horizFov, vertFov);
1785
1786    // Need to flatten again in case of overrides
1787    paramsFlattened = newParams.flatten();
1788    params = newParams;
1789
1790    return OK;
1791}
1792
1793status_t Parameters::updateRequest(CameraMetadata *request) const {
1794    ATRACE_CALL();
1795    status_t res;
1796
1797    /**
1798     * Mixin default important security values
1799     * - android.led.transmit = defaulted ON
1800     */
1801    camera_metadata_ro_entry_t entry = staticInfo(ANDROID_LED_AVAILABLE_LEDS,
1802                                                  /*minimumCount*/0,
1803                                                  /*maximumCount*/0,
1804                                                  /*required*/false);
1805    for(size_t i = 0; i < entry.count; ++i) {
1806        uint8_t led = entry.data.u8[i];
1807
1808        switch(led) {
1809            // Transmit LED is unconditionally on when using
1810            // the android.hardware.Camera API
1811            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1812                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1813                res = request->update(ANDROID_LED_TRANSMIT,
1814                                      &transmitDefault, 1);
1815                if (res != OK) return res;
1816                break;
1817            }
1818        }
1819    }
1820
1821    /**
1822     * Construct metadata from parameters
1823     */
1824
1825    uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
1826    res = request->update(ANDROID_REQUEST_METADATA_MODE,
1827            &metadataMode, 1);
1828    if (res != OK) return res;
1829
1830    camera_metadata_entry_t intent =
1831            request->find(ANDROID_CONTROL_CAPTURE_INTENT);
1832    if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
1833        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1834                fastInfo.bestStillCaptureFpsRange, 2);
1835    } else {
1836        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1837                previewFpsRange, 2);
1838    }
1839    if (res != OK) return res;
1840
1841    uint8_t reqWbLock = autoWhiteBalanceLock ?
1842            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1843    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1844            &reqWbLock, 1);
1845
1846    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1847            &effectMode, 1);
1848    if (res != OK) return res;
1849    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1850            &antibandingMode, 1);
1851    if (res != OK) return res;
1852
1853    // android.hardware.Camera requires that when face detect is enabled, the
1854    // camera is in a face-priority mode. HAL2 splits this into separate parts
1855    // (face detection statistics and face priority scene mode). Map from other
1856    // to the other.
1857    bool sceneModeActive =
1858            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_DISABLED;
1859    uint8_t reqControlMode = ANDROID_CONTROL_MODE_AUTO;
1860    if (enableFaceDetect || sceneModeActive) {
1861        reqControlMode = ANDROID_CONTROL_MODE_USE_SCENE_MODE;
1862    }
1863    res = request->update(ANDROID_CONTROL_MODE,
1864            &reqControlMode, 1);
1865    if (res != OK) return res;
1866
1867    uint8_t reqSceneMode =
1868            sceneModeActive ? sceneMode :
1869            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1870            (uint8_t)ANDROID_CONTROL_SCENE_MODE_DISABLED;
1871    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1872            &reqSceneMode, 1);
1873    if (res != OK) return res;
1874
1875    uint8_t reqFlashMode = ANDROID_FLASH_MODE_OFF;
1876    uint8_t reqAeMode = ANDROID_CONTROL_AE_MODE_OFF;
1877    switch (flashMode) {
1878        case Parameters::FLASH_MODE_OFF:
1879            reqAeMode = ANDROID_CONTROL_AE_MODE_ON; break;
1880        case Parameters::FLASH_MODE_AUTO:
1881            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; break;
1882        case Parameters::FLASH_MODE_ON:
1883            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH; break;
1884        case Parameters::FLASH_MODE_TORCH:
1885            reqAeMode = ANDROID_CONTROL_AE_MODE_ON;
1886            reqFlashMode = ANDROID_FLASH_MODE_TORCH;
1887            break;
1888        case Parameters::FLASH_MODE_RED_EYE:
1889            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; break;
1890        default:
1891            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1892                    cameraId, flashMode);
1893                return BAD_VALUE;
1894    }
1895    res = request->update(ANDROID_FLASH_MODE,
1896            &reqFlashMode, 1);
1897    if (res != OK) return res;
1898    res = request->update(ANDROID_CONTROL_AE_MODE,
1899            &reqAeMode, 1);
1900    if (res != OK) return res;
1901
1902    uint8_t reqAeLock = autoExposureLock ?
1903            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1904    res = request->update(ANDROID_CONTROL_AE_LOCK,
1905            &reqAeLock, 1);
1906    if (res != OK) return res;
1907
1908    res = request->update(ANDROID_CONTROL_AWB_MODE,
1909            &wbMode, 1);
1910    if (res != OK) return res;
1911
1912    float reqFocusDistance = 0; // infinity focus in diopters
1913    uint8_t reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1914    switch (focusMode) {
1915        case Parameters::FOCUS_MODE_AUTO:
1916        case Parameters::FOCUS_MODE_MACRO:
1917        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1918        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1919        case Parameters::FOCUS_MODE_EDOF:
1920            reqFocusMode = focusMode;
1921            break;
1922        case Parameters::FOCUS_MODE_INFINITY:
1923        case Parameters::FOCUS_MODE_FIXED:
1924            reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1925            break;
1926        default:
1927                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1928                        cameraId, focusMode);
1929                return BAD_VALUE;
1930    }
1931    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1932            &reqFocusDistance, 1);
1933    if (res != OK) return res;
1934    res = request->update(ANDROID_CONTROL_AF_MODE,
1935            &reqFocusMode, 1);
1936    if (res != OK) return res;
1937
1938    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1939    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1940    for (size_t i = 0, j = 0; i < reqFocusingAreasSize; i += 5, j++) {
1941        if (focusingAreas[j].weight != 0) {
1942            reqFocusingAreas[i + 0] =
1943                    normalizedXToArray(focusingAreas[j].left);
1944            reqFocusingAreas[i + 1] =
1945                    normalizedYToArray(focusingAreas[j].top);
1946            reqFocusingAreas[i + 2] =
1947                    normalizedXToArray(focusingAreas[j].right);
1948            reqFocusingAreas[i + 3] =
1949                    normalizedYToArray(focusingAreas[j].bottom);
1950        } else {
1951            reqFocusingAreas[i + 0] = 0;
1952            reqFocusingAreas[i + 1] = 0;
1953            reqFocusingAreas[i + 2] = 0;
1954            reqFocusingAreas[i + 3] = 0;
1955        }
1956        reqFocusingAreas[i + 4] = focusingAreas[j].weight;
1957    }
1958    res = request->update(ANDROID_CONTROL_AF_REGIONS,
1959            reqFocusingAreas, reqFocusingAreasSize);
1960    if (res != OK) return res;
1961    delete[] reqFocusingAreas;
1962
1963    res = request->update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1964            &exposureCompensation, 1);
1965    if (res != OK) return res;
1966
1967    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1968    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1969    for (size_t i = 0, j = 0; i < reqMeteringAreasSize; i += 5, j++) {
1970        if (meteringAreas[j].weight != 0) {
1971            reqMeteringAreas[i + 0] =
1972                normalizedXToArray(meteringAreas[j].left);
1973            reqMeteringAreas[i + 1] =
1974                normalizedYToArray(meteringAreas[j].top);
1975            reqMeteringAreas[i + 2] =
1976                normalizedXToArray(meteringAreas[j].right);
1977            reqMeteringAreas[i + 3] =
1978                normalizedYToArray(meteringAreas[j].bottom);
1979        } else {
1980            reqMeteringAreas[i + 0] = 0;
1981            reqMeteringAreas[i + 1] = 0;
1982            reqMeteringAreas[i + 2] = 0;
1983            reqMeteringAreas[i + 3] = 0;
1984        }
1985        reqMeteringAreas[i + 4] = meteringAreas[j].weight;
1986    }
1987    res = request->update(ANDROID_CONTROL_AE_REGIONS,
1988            reqMeteringAreas, reqMeteringAreasSize);
1989    if (res != OK) return res;
1990
1991    // Set awb regions to be the same as the metering regions if allowed
1992    size_t maxAwbRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
1993            Parameters::NUM_REGION, Parameters::NUM_REGION).
1994            data.i32[Parameters::REGION_AWB];
1995    if (maxAwbRegions > 0) {
1996        if (maxAwbRegions >= meteringAreas.size()) {
1997            res = request->update(ANDROID_CONTROL_AWB_REGIONS,
1998                    reqMeteringAreas, reqMeteringAreasSize);
1999        } else {
2000            // Ensure the awb regions are zeroed if the region count is too high.
2001            int32_t zeroedAwbAreas[5] = {0, 0, 0, 0, 0};
2002            res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2003                    zeroedAwbAreas, sizeof(zeroedAwbAreas)/sizeof(int32_t));
2004        }
2005        if (res != OK) return res;
2006    }
2007
2008    delete[] reqMeteringAreas;
2009
2010    /* don't include jpeg thumbnail size - it's valid for
2011       it to be set to (0,0), meaning 'no thumbnail' */
2012    CropRegion crop = calculateCropRegion( (CropRegion::Outputs)(
2013            CropRegion::OUTPUT_PREVIEW     |
2014            CropRegion::OUTPUT_VIDEO       |
2015            CropRegion::OUTPUT_PICTURE    ));
2016    int32_t reqCropRegion[4] = {
2017        static_cast<int32_t>(crop.left),
2018        static_cast<int32_t>(crop.top),
2019        static_cast<int32_t>(crop.width),
2020        static_cast<int32_t>(crop.height)
2021    };
2022    res = request->update(ANDROID_SCALER_CROP_REGION,
2023            reqCropRegion, 4);
2024    if (res != OK) return res;
2025
2026    uint8_t reqVstabMode = videoStabilization ?
2027            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON :
2028            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2029    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2030            &reqVstabMode, 1);
2031    if (res != OK) return res;
2032
2033    uint8_t reqFaceDetectMode = enableFaceDetect ?
2034            fastInfo.bestFaceDetectMode :
2035            (uint8_t)ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2036    res = request->update(ANDROID_STATISTICS_FACE_DETECT_MODE,
2037            &reqFaceDetectMode, 1);
2038    if (res != OK) return res;
2039
2040    return OK;
2041}
2042
2043status_t Parameters::updateRequestJpeg(CameraMetadata *request) const {
2044    status_t res;
2045
2046    res = request->update(ANDROID_JPEG_THUMBNAIL_SIZE,
2047            jpegThumbSize, 2);
2048    if (res != OK) return res;
2049    res = request->update(ANDROID_JPEG_THUMBNAIL_QUALITY,
2050            &jpegThumbQuality, 1);
2051    if (res != OK) return res;
2052    res = request->update(ANDROID_JPEG_QUALITY,
2053            &jpegQuality, 1);
2054    if (res != OK) return res;
2055    res = request->update(
2056            ANDROID_JPEG_ORIENTATION,
2057            &jpegRotation, 1);
2058    if (res != OK) return res;
2059
2060    if (gpsEnabled) {
2061        res = request->update(
2062                ANDROID_JPEG_GPS_COORDINATES,
2063                gpsCoordinates, 3);
2064        if (res != OK) return res;
2065        res = request->update(
2066                ANDROID_JPEG_GPS_TIMESTAMP,
2067                &gpsTimestamp, 1);
2068        if (res != OK) return res;
2069        res = request->update(
2070                ANDROID_JPEG_GPS_PROCESSING_METHOD,
2071                gpsProcessingMethod);
2072        if (res != OK) return res;
2073    } else {
2074        res = request->erase(ANDROID_JPEG_GPS_COORDINATES);
2075        if (res != OK) return res;
2076        res = request->erase(ANDROID_JPEG_GPS_TIMESTAMP);
2077        if (res != OK) return res;
2078        res = request->erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
2079        if (res != OK) return res;
2080    }
2081    return OK;
2082}
2083
2084
2085const char* Parameters::getStateName(State state) {
2086#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
2087    switch(state) {
2088        CASE_ENUM_TO_CHAR(DISCONNECTED)
2089        CASE_ENUM_TO_CHAR(STOPPED)
2090        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
2091        CASE_ENUM_TO_CHAR(PREVIEW)
2092        CASE_ENUM_TO_CHAR(RECORD)
2093        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
2094        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
2095        default:
2096            return "Unknown state!";
2097            break;
2098    }
2099#undef CASE_ENUM_TO_CHAR
2100}
2101
2102int Parameters::formatStringToEnum(const char *format) {
2103    return
2104        !format ?
2105            HAL_PIXEL_FORMAT_YCrCb_420_SP :
2106        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2107            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2108        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2109            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2110        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2111            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
2112        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2113            HAL_PIXEL_FORMAT_YV12 :         // YV12
2114        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2115            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
2116        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2117            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
2118        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2119            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
2120        -1;
2121}
2122
2123const char* Parameters::formatEnumToString(int format) {
2124    const char *fmt;
2125    switch(format) {
2126        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2127            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2128            break;
2129        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2130            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2131            break;
2132        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2133            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2134            break;
2135        case HAL_PIXEL_FORMAT_YV12:        // YV12
2136            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2137            break;
2138        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
2139            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2140            break;
2141        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
2142            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2143            break;
2144        case HAL_PIXEL_FORMAT_RAW_SENSOR:
2145            ALOGW("Raw sensor preview format requested.");
2146            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2147            break;
2148        default:
2149            ALOGE("%s: Unknown preview format: %x",
2150                    __FUNCTION__,  format);
2151            fmt = NULL;
2152            break;
2153    }
2154    return fmt;
2155}
2156
2157int Parameters::wbModeStringToEnum(const char *wbMode) {
2158    return
2159        !wbMode ?
2160            ANDROID_CONTROL_AWB_MODE_AUTO :
2161        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2162            ANDROID_CONTROL_AWB_MODE_AUTO :
2163        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2164            ANDROID_CONTROL_AWB_MODE_INCANDESCENT :
2165        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2166            ANDROID_CONTROL_AWB_MODE_FLUORESCENT :
2167        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2168            ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT :
2169        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2170            ANDROID_CONTROL_AWB_MODE_DAYLIGHT :
2171        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2172            ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT :
2173        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2174            ANDROID_CONTROL_AWB_MODE_TWILIGHT :
2175        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2176            ANDROID_CONTROL_AWB_MODE_SHADE :
2177        -1;
2178}
2179
2180const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
2181    switch (wbMode) {
2182        case ANDROID_CONTROL_AWB_MODE_AUTO:
2183            return CameraParameters::WHITE_BALANCE_AUTO;
2184        case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
2185            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
2186        case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
2187            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
2188        case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
2189            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
2190        case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
2191            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
2192        case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
2193            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
2194        case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
2195            return CameraParameters::WHITE_BALANCE_TWILIGHT;
2196        case ANDROID_CONTROL_AWB_MODE_SHADE:
2197            return CameraParameters::WHITE_BALANCE_SHADE;
2198        default:
2199            ALOGE("%s: Unknown AWB mode enum: %d",
2200                    __FUNCTION__, wbMode);
2201            return "unknown";
2202    }
2203}
2204
2205int Parameters::effectModeStringToEnum(const char *effectMode) {
2206    return
2207        !effectMode ?
2208            ANDROID_CONTROL_EFFECT_MODE_OFF :
2209        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2210            ANDROID_CONTROL_EFFECT_MODE_OFF :
2211        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2212            ANDROID_CONTROL_EFFECT_MODE_MONO :
2213        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2214            ANDROID_CONTROL_EFFECT_MODE_NEGATIVE :
2215        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2216            ANDROID_CONTROL_EFFECT_MODE_SOLARIZE :
2217        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2218            ANDROID_CONTROL_EFFECT_MODE_SEPIA :
2219        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2220            ANDROID_CONTROL_EFFECT_MODE_POSTERIZE :
2221        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2222            ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD :
2223        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2224            ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD :
2225        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2226            ANDROID_CONTROL_EFFECT_MODE_AQUA :
2227        -1;
2228}
2229
2230int Parameters::abModeStringToEnum(const char *abMode) {
2231    return
2232        !abMode ?
2233            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2234        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2235            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2236        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2237            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF :
2238        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2239            ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ :
2240        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2241            ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ :
2242        -1;
2243}
2244
2245int Parameters::sceneModeStringToEnum(const char *sceneMode) {
2246    return
2247        !sceneMode ?
2248            ANDROID_CONTROL_SCENE_MODE_DISABLED :
2249        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2250            ANDROID_CONTROL_SCENE_MODE_DISABLED :
2251        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2252            ANDROID_CONTROL_SCENE_MODE_ACTION :
2253        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2254            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2255        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2256            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2257        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2258            ANDROID_CONTROL_SCENE_MODE_NIGHT :
2259        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2260            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2261        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2262            ANDROID_CONTROL_SCENE_MODE_THEATRE :
2263        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2264            ANDROID_CONTROL_SCENE_MODE_BEACH :
2265        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2266            ANDROID_CONTROL_SCENE_MODE_SNOW :
2267        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2268            ANDROID_CONTROL_SCENE_MODE_SUNSET :
2269        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2270            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2271        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2272            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2273        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2274            ANDROID_CONTROL_SCENE_MODE_SPORTS :
2275        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2276            ANDROID_CONTROL_SCENE_MODE_PARTY :
2277        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2278            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2279        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2280            ANDROID_CONTROL_SCENE_MODE_BARCODE:
2281        -1;
2282}
2283
2284Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
2285        const char *flashMode) {
2286    return
2287        !flashMode ?
2288            Parameters::FLASH_MODE_INVALID :
2289        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2290            Parameters::FLASH_MODE_OFF :
2291        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2292            Parameters::FLASH_MODE_AUTO :
2293        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2294            Parameters::FLASH_MODE_ON :
2295        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2296            Parameters::FLASH_MODE_RED_EYE :
2297        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2298            Parameters::FLASH_MODE_TORCH :
2299        Parameters::FLASH_MODE_INVALID;
2300}
2301
2302const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
2303    switch (flashMode) {
2304        case FLASH_MODE_OFF:
2305            return CameraParameters::FLASH_MODE_OFF;
2306        case FLASH_MODE_AUTO:
2307            return CameraParameters::FLASH_MODE_AUTO;
2308        case FLASH_MODE_ON:
2309            return CameraParameters::FLASH_MODE_ON;
2310        case FLASH_MODE_RED_EYE:
2311            return CameraParameters::FLASH_MODE_RED_EYE;
2312        case FLASH_MODE_TORCH:
2313            return CameraParameters::FLASH_MODE_TORCH;
2314        default:
2315            ALOGE("%s: Unknown flash mode enum %d",
2316                    __FUNCTION__, flashMode);
2317            return "unknown";
2318    }
2319}
2320
2321Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
2322        const char *focusMode) {
2323    return
2324        !focusMode ?
2325            Parameters::FOCUS_MODE_INVALID :
2326        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2327            Parameters::FOCUS_MODE_AUTO :
2328        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2329            Parameters::FOCUS_MODE_INFINITY :
2330        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2331            Parameters::FOCUS_MODE_MACRO :
2332        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2333            Parameters::FOCUS_MODE_FIXED :
2334        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2335            Parameters::FOCUS_MODE_EDOF :
2336        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
2337            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
2338        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
2339            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
2340        Parameters::FOCUS_MODE_INVALID;
2341}
2342
2343const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
2344    switch (focusMode) {
2345        case FOCUS_MODE_AUTO:
2346            return CameraParameters::FOCUS_MODE_AUTO;
2347        case FOCUS_MODE_MACRO:
2348            return CameraParameters::FOCUS_MODE_MACRO;
2349        case FOCUS_MODE_CONTINUOUS_VIDEO:
2350            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
2351        case FOCUS_MODE_CONTINUOUS_PICTURE:
2352            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
2353        case FOCUS_MODE_EDOF:
2354            return CameraParameters::FOCUS_MODE_EDOF;
2355        case FOCUS_MODE_INFINITY:
2356            return CameraParameters::FOCUS_MODE_INFINITY;
2357        case FOCUS_MODE_FIXED:
2358            return CameraParameters::FOCUS_MODE_FIXED;
2359        default:
2360            ALOGE("%s: Unknown focus mode enum: %d",
2361                    __FUNCTION__, focusMode);
2362            return "unknown";
2363    }
2364}
2365
2366Parameters::Parameters::lightFxMode_t Parameters::lightFxStringToEnum(
2367        const char *lightFxMode) {
2368    return
2369        !lightFxMode ?
2370            Parameters::LIGHTFX_NONE :
2371        !strcmp(lightFxMode, CameraParameters::LIGHTFX_LOWLIGHT) ?
2372            Parameters::LIGHTFX_LOWLIGHT :
2373        !strcmp(lightFxMode, CameraParameters::LIGHTFX_HDR) ?
2374            Parameters::LIGHTFX_HDR :
2375        Parameters::LIGHTFX_NONE;
2376}
2377
2378status_t Parameters::parseAreas(const char *areasCStr,
2379        Vector<Parameters::Area> *areas) {
2380    static const size_t NUM_FIELDS = 5;
2381    areas->clear();
2382    if (areasCStr == NULL) {
2383        // If no key exists, use default (0,0,0,0,0)
2384        areas->push();
2385        return OK;
2386    }
2387    String8 areasStr(areasCStr);
2388    ssize_t areaStart = areasStr.find("(", 0) + 1;
2389    while (areaStart != 0) {
2390        const char* area = areasStr.string() + areaStart;
2391        char *numEnd;
2392        int vals[NUM_FIELDS];
2393        for (size_t i = 0; i < NUM_FIELDS; i++) {
2394            errno = 0;
2395            vals[i] = strtol(area, &numEnd, 10);
2396            if (errno || numEnd == area) return BAD_VALUE;
2397            area = numEnd + 1;
2398        }
2399        areas->push(Parameters::Area(
2400            vals[0], vals[1], vals[2], vals[3], vals[4]) );
2401        areaStart = areasStr.find("(", areaStart) + 1;
2402    }
2403    return OK;
2404}
2405
2406status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
2407                                      size_t maxRegions,
2408                                      AreaKind areaKind) const {
2409    // Definition of valid area can be found in
2410    // include/camera/CameraParameters.h
2411    if (areas.size() == 0) return BAD_VALUE;
2412    if (areas.size() == 1) {
2413        if (areas[0].left == 0 &&
2414                areas[0].top == 0 &&
2415                areas[0].right == 0 &&
2416                areas[0].bottom == 0 &&
2417                areas[0].weight == 0) {
2418            // Single (0,0,0,0,0) entry is always valid (== driver decides)
2419            return OK;
2420        }
2421    }
2422
2423    // fixed focus can only set (0,0,0,0,0) focus area
2424    if (areaKind == AREA_KIND_FOCUS && focusMode == FOCUS_MODE_FIXED) {
2425        return BAD_VALUE;
2426    }
2427
2428    if (areas.size() > maxRegions) {
2429        ALOGE("%s: Too many areas requested: %d",
2430                __FUNCTION__, areas.size());
2431        return BAD_VALUE;
2432    }
2433
2434    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2435         a != areas.end(); a++) {
2436        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2437        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2438        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2439        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2440        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2441        if (a->left >= a->right) return BAD_VALUE;
2442        if (a->top >= a->bottom) return BAD_VALUE;
2443    }
2444    return OK;
2445}
2446
2447bool Parameters::boolFromString(const char *boolStr) {
2448    return !boolStr ? false :
2449        !strcmp(boolStr, CameraParameters::TRUE) ? true :
2450        false;
2451}
2452
2453int Parameters::degToTransform(int degrees, bool mirror) {
2454    if (!mirror) {
2455        if (degrees == 0) return 0;
2456        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2457        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2458        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2459    } else {  // Do mirror (horizontal flip)
2460        if (degrees == 0) {           // FLIP_H and ROT_0
2461            return HAL_TRANSFORM_FLIP_H;
2462        } else if (degrees == 90) {   // FLIP_H and ROT_90
2463            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2464        } else if (degrees == 180) {  // FLIP_H and ROT_180
2465            return HAL_TRANSFORM_FLIP_V;
2466        } else if (degrees == 270) {  // FLIP_H and ROT_270
2467            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2468        }
2469    }
2470    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2471    return -1;
2472}
2473
2474int Parameters::cropXToArray(int x) const {
2475    ALOG_ASSERT(x >= 0, "Crop-relative X coordinate = '%d' is out of bounds"
2476                         "(lower = 0)", x);
2477
2478    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2479    ALOG_ASSERT(x < previewCrop.width, "Crop-relative X coordinate = '%d' "
2480                    "is out of bounds (upper = %f)", x, previewCrop.width);
2481
2482    int ret = x + previewCrop.left;
2483
2484    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayWidth),
2485        "Calculated pixel array value X = '%d' is out of bounds (upper = %d)",
2486        ret, fastInfo.arrayWidth);
2487    return ret;
2488}
2489
2490int Parameters::cropYToArray(int y) const {
2491    ALOG_ASSERT(y >= 0, "Crop-relative Y coordinate = '%d' is out of bounds "
2492        "(lower = 0)", y);
2493
2494    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2495    ALOG_ASSERT(y < previewCrop.height, "Crop-relative Y coordinate = '%d' is "
2496                "out of bounds (upper = %f)", y, previewCrop.height);
2497
2498    int ret = y + previewCrop.top;
2499
2500    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayHeight),
2501        "Calculated pixel array value Y = '%d' is out of bounds (upper = %d)",
2502        ret, fastInfo.arrayHeight);
2503
2504    return ret;
2505
2506}
2507
2508int Parameters::normalizedXToCrop(int x) const {
2509    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2510    return (x + 1000) * (previewCrop.width - 1) / 2000;
2511}
2512
2513int Parameters::normalizedYToCrop(int y) const {
2514    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2515    return (y + 1000) * (previewCrop.height - 1) / 2000;
2516}
2517
2518int Parameters::arrayXToCrop(int x) const {
2519    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2520    return x - previewCrop.left;
2521}
2522
2523int Parameters::arrayYToCrop(int y) const {
2524    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2525    return y - previewCrop.top;
2526}
2527
2528int Parameters::cropXToNormalized(int x) const {
2529    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2530    return x * 2000 / (previewCrop.width - 1) - 1000;
2531}
2532
2533int Parameters::cropYToNormalized(int y) const {
2534    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2535    return y * 2000 / (previewCrop.height - 1) - 1000;
2536}
2537
2538int Parameters::arrayXToNormalized(int width) const {
2539    int ret = cropXToNormalized(arrayXToCrop(width));
2540
2541    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of "
2542        "lower bounds %d", ret);
2543    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of "
2544        "upper bounds %d", ret);
2545
2546    // Work-around for HAL pre-scaling the coordinates themselves
2547    if (quirks.meteringCropRegion) {
2548        return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2549    }
2550
2551    return ret;
2552}
2553
2554int Parameters::arrayYToNormalized(int height) const {
2555    int ret = cropYToNormalized(arrayYToCrop(height));
2556
2557    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds"
2558        " %d", ret);
2559    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds"
2560        " %d", ret);
2561
2562    // Work-around for HAL pre-scaling the coordinates themselves
2563    if (quirks.meteringCropRegion) {
2564        return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2565    }
2566
2567    return ret;
2568}
2569
2570int Parameters::normalizedXToArray(int x) const {
2571
2572    // Work-around for HAL pre-scaling the coordinates themselves
2573    if (quirks.meteringCropRegion) {
2574        return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2575    }
2576
2577    return cropXToArray(normalizedXToCrop(x));
2578}
2579
2580int Parameters::normalizedYToArray(int y) const {
2581    // Work-around for HAL pre-scaling the coordinates themselves
2582    if (quirks.meteringCropRegion) {
2583        return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2584    }
2585
2586    return cropYToArray(normalizedYToCrop(y));
2587}
2588
2589status_t Parameters::getFilteredPreviewSizes(Size limit, Vector<Size> *sizes) {
2590    if (info == NULL) {
2591        ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
2592        return NO_INIT;
2593    }
2594    if (sizes == NULL) {
2595        ALOGE("%s: Input size is null", __FUNCTION__);
2596        return BAD_VALUE;
2597    }
2598
2599    const size_t SIZE_COUNT = sizeof(Size) / sizeof(int);
2600    camera_metadata_ro_entry_t availableProcessedSizes =
2601        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, SIZE_COUNT);
2602    if (availableProcessedSizes.count < SIZE_COUNT) return BAD_VALUE;
2603
2604    Size previewSize;
2605    for (size_t i = 0; i < availableProcessedSizes.count; i += SIZE_COUNT) {
2606        previewSize.width = availableProcessedSizes.data.i32[i];
2607        previewSize.height = availableProcessedSizes.data.i32[i+1];
2608            // Need skip the preview sizes that are too large.
2609            if (previewSize.width <= limit.width &&
2610                    previewSize.height <= limit.height) {
2611                sizes->push(previewSize);
2612            }
2613    }
2614    if (sizes->isEmpty()) {
2615        ALOGE("generated preview size list is empty!!");
2616        return BAD_VALUE;
2617    }
2618    return OK;
2619}
2620
2621Parameters::Size Parameters::getMaxSizeForRatio(
2622        float ratio, const int32_t* sizeArray, size_t count) {
2623    ALOG_ASSERT(sizeArray != NULL, "size array shouldn't be NULL");
2624    ALOG_ASSERT(count >= 2 && count % 2 == 0, "count must be a positive even number");
2625
2626    Size maxSize = {0, 0};
2627    for (size_t i = 0; i < count; i += 2) {
2628        if (sizeArray[i] > 0 && sizeArray[i+1] > 0) {
2629            float curRatio = static_cast<float>(sizeArray[i]) / sizeArray[i+1];
2630            if (fabs(curRatio - ratio) < ASPECT_RATIO_TOLERANCE && maxSize.width < sizeArray[i]) {
2631                maxSize.width = sizeArray[i];
2632                maxSize.height = sizeArray[i+1];
2633            }
2634        }
2635    }
2636
2637    if (maxSize.width == 0 || maxSize.height == 0) {
2638        maxSize.width = sizeArray[0];
2639        maxSize.height = sizeArray[1];
2640        ALOGW("Unable to find the size to match the given aspect ratio %f."
2641                "Fall back to %d x %d", ratio, maxSize.width, maxSize.height);
2642    }
2643
2644    return maxSize;
2645}
2646
2647Parameters::CropRegion Parameters::calculateCropRegion(
2648                            Parameters::CropRegion::Outputs outputs) const {
2649
2650    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2651
2652    // Need to convert zoom index into a crop rectangle. The rectangle is
2653    // chosen to maximize its area on the sensor
2654
2655    camera_metadata_ro_entry_t maxDigitalZoom =
2656            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
2657    // For each zoom step by how many pixels more do we change the zoom
2658    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2659            (NUM_ZOOM_STEPS-1);
2660    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2661    // via interpolating zoom step into a zoom ratio
2662    float zoomRatio = 1 + zoomIncrement * zoom;
2663    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2664        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2665        maxDigitalZoom.data.f[0], zoomRatio);
2666
2667    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2668          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2669          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2670          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2671
2672    /*
2673     * Assumption: On the HAL side each stream buffer calculates its crop
2674     * rectangle as follows:
2675     *   cropRect = (zoomLeft, zoomRight,
2676     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
2677     *
2678     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2679     *      (we can then get into trouble if the cropHeight > arrayHeight).
2680     * By selecting the zoomRatio based on the smallest outputRatio, we
2681     * guarantee this will never happen.
2682     */
2683
2684    // Enumerate all possible output sizes, select the one with the smallest
2685    // aspect ratio
2686    float minOutputWidth, minOutputHeight, minOutputRatio;
2687    {
2688        float outputSizes[][2] = {
2689            { static_cast<float>(previewWidth),
2690              static_cast<float>(previewHeight) },
2691            { static_cast<float>(videoWidth),
2692              static_cast<float>(videoHeight) },
2693            { static_cast<float>(jpegThumbSize[0]),
2694              static_cast<float>(jpegThumbSize[1]) },
2695            { static_cast<float>(pictureWidth),
2696              static_cast<float>(pictureHeight) },
2697        };
2698
2699        minOutputWidth = outputSizes[0][0];
2700        minOutputHeight = outputSizes[0][1];
2701        minOutputRatio = minOutputWidth / minOutputHeight;
2702        for (unsigned int i = 0;
2703             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2704             ++i) {
2705
2706            // skip over outputs we don't want to consider for the crop region
2707            if ( !((1 << i) & outputs) ) {
2708                continue;
2709            }
2710
2711            float outputWidth = outputSizes[i][0];
2712            float outputHeight = outputSizes[i][1];
2713            float outputRatio = outputWidth / outputHeight;
2714
2715            if (minOutputRatio > outputRatio) {
2716                minOutputRatio = outputRatio;
2717                minOutputWidth = outputWidth;
2718                minOutputHeight = outputHeight;
2719            }
2720
2721            // and then use this output ratio instead of preview output ratio
2722            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2723                  outputRatio, outputWidth, outputHeight, minOutputRatio);
2724        }
2725    }
2726
2727    /* Ensure that the width/height never go out of bounds
2728     * by scaling across a diffent dimension if an out-of-bounds
2729     * possibility exists.
2730     *
2731     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2732     * calculating the zoomWidth from zoomHeight we'll actually get a
2733     * zoomheight > arrayheight
2734     */
2735    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2736    if (minOutputRatio >= arrayRatio) {
2737        // Adjust the height based on the width
2738        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
2739        zoomHeight = zoomWidth *
2740                minOutputHeight / minOutputWidth;
2741
2742    } else {
2743        // Adjust the width based on the height
2744        zoomHeight = fastInfo.arrayHeight / zoomRatio;
2745        zoomWidth = zoomHeight *
2746                minOutputWidth / minOutputHeight;
2747    }
2748    // centering the zoom area within the active area
2749    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2750    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2751
2752    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2753        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2754
2755
2756    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2757    return crop;
2758}
2759
2760status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)
2761        const {
2762    camera_metadata_ro_entry_t sensorSize =
2763            staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
2764    if (!sensorSize.count) return NO_INIT;
2765
2766    float arrayAspect = static_cast<float>(fastInfo.arrayWidth) /
2767            fastInfo.arrayHeight;
2768    float stillAspect = static_cast<float>(pictureWidth) / pictureHeight;
2769    ALOGV("Array aspect: %f, still aspect: %f", arrayAspect, stillAspect);
2770
2771    // The crop factors from the full sensor array to the still picture crop
2772    // region
2773    float horizCropFactor = 1.f;
2774    float vertCropFactor = 1.f;
2775
2776    /**
2777     * Need to calculate the still image field of view based on the total pixel
2778     * array field of view, and the relative aspect ratios of the pixel array
2779     * and output streams.
2780     *
2781     * Special treatment for quirky definition of crop region and relative
2782     * stream cropping.
2783     */
2784    if (quirks.meteringCropRegion) {
2785        // Use max of preview and video as first crop
2786        float previewAspect = static_cast<float>(previewWidth) / previewHeight;
2787        float videoAspect = static_cast<float>(videoWidth) / videoHeight;
2788        if (videoAspect > previewAspect) {
2789            previewAspect = videoAspect;
2790        }
2791        // First crop sensor to preview aspect ratio
2792        if (arrayAspect < previewAspect) {
2793            vertCropFactor = arrayAspect / previewAspect;
2794        } else {
2795            horizCropFactor = previewAspect / arrayAspect;
2796        }
2797        // Second crop to still aspect ratio
2798        if (stillAspect < previewAspect) {
2799            horizCropFactor *= stillAspect / previewAspect;
2800        } else {
2801            vertCropFactor *= previewAspect / stillAspect;
2802        }
2803    } else {
2804        /**
2805         * Crop are just a function of just the still/array relative aspect
2806         * ratios. Since each stream will maximize its area within the crop
2807         * region, and for FOV we assume a full-sensor crop region, we only ever
2808         * crop the FOV either vertically or horizontally, never both.
2809         */
2810        horizCropFactor = (arrayAspect > stillAspect) ?
2811                (stillAspect / arrayAspect) : 1.f;
2812        vertCropFactor = (arrayAspect < stillAspect) ?
2813                (arrayAspect / stillAspect) : 1.f;
2814    }
2815    ALOGV("Horiz crop factor: %f, vert crop fact: %f",
2816            horizCropFactor, vertCropFactor);
2817    /**
2818     * Basic field of view formula is:
2819     *   angle of view = 2 * arctangent ( d / 2f )
2820     * where d is the physical sensor dimension of interest, and f is
2821     * the focal length. This only applies to rectilinear sensors, for focusing
2822     * at distances >> f, etc.
2823     */
2824    if (horizFov != NULL) {
2825        *horizFov = 180 / M_PI * 2 *
2826                atanf(horizCropFactor * sensorSize.data.f[0] /
2827                        (2 * fastInfo.minFocalLength));
2828    }
2829    if (vertFov != NULL) {
2830        *vertFov = 180 / M_PI * 2 *
2831                atanf(vertCropFactor * sensorSize.data.f[1] /
2832                        (2 * fastInfo.minFocalLength));
2833    }
2834    return OK;
2835}
2836
2837int32_t Parameters::fpsFromRange(int32_t /*min*/, int32_t max) const {
2838    return max;
2839}
2840
2841}; // namespace camera2
2842}; // namespace android
2843