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