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