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