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