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