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