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