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