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