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