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