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