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