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