Parameters.cpp revision f128dc51c81e6b831806e0de505e4edbb02b7e71
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 <math.h>
22#include <stdlib.h>
23
24#include "Parameters.h"
25#include "system/camera.h"
26#include "camera/CameraParameters.h"
27
28namespace android {
29namespace camera2 {
30
31Parameters::Parameters(int cameraId,
32        int cameraFacing) :
33        cameraId(cameraId),
34        cameraFacing(cameraFacing),
35        info(NULL) {
36}
37
38Parameters::~Parameters() {
39}
40
41status_t Parameters::initialize(const CameraMetadata *info) {
42    status_t res;
43
44    if (info->entryCount() == 0) {
45        ALOGE("%s: No static information provided!", __FUNCTION__);
46        return BAD_VALUE;
47    }
48    Parameters::info = info;
49
50    res = buildFastInfo();
51    if (res != OK) return res;
52
53    CameraParameters params;
54
55    camera_metadata_ro_entry_t availableProcessedSizes =
56        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
57    if (!availableProcessedSizes.count) return NO_INIT;
58
59    // TODO: Pick more intelligently
60    previewWidth = availableProcessedSizes.data.i32[0];
61    previewHeight = availableProcessedSizes.data.i32[1];
62    videoWidth = previewWidth;
63    videoHeight = previewHeight;
64
65    params.setPreviewSize(previewWidth, previewHeight);
66    params.setVideoSize(videoWidth, videoHeight);
67    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
68            String8::format("%dx%d",
69                    previewWidth, previewHeight));
70    {
71        String8 supportedPreviewSizes;
72        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
73            if (i != 0) supportedPreviewSizes += ",";
74            supportedPreviewSizes += String8::format("%dx%d",
75                    availableProcessedSizes.data.i32[i],
76                    availableProcessedSizes.data.i32[i+1]);
77        }
78        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
79                supportedPreviewSizes);
80        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
81                supportedPreviewSizes);
82    }
83
84    camera_metadata_ro_entry_t availableFpsRanges =
85        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
86    if (!availableFpsRanges.count) return NO_INIT;
87
88    previewFpsRange[0] = availableFpsRanges.data.i32[0];
89    previewFpsRange[1] = availableFpsRanges.data.i32[1];
90
91    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
92            String8::format("%d,%d",
93                    previewFpsRange[0],
94                    previewFpsRange[1]));
95
96    {
97        String8 supportedPreviewFpsRange;
98        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
99            if (i != 0) supportedPreviewFpsRange += ",";
100            supportedPreviewFpsRange += String8::format("(%d,%d)",
101                    availableFpsRanges.data.i32[i],
102                    availableFpsRanges.data.i32[i+1]);
103        }
104        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
105                supportedPreviewFpsRange);
106    }
107
108    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
109    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
110            formatEnumToString(previewFormat)); // NV21
111
112    previewTransform = degToTransform(0,
113            cameraFacing == CAMERA_FACING_FRONT);
114
115    camera_metadata_ro_entry_t availableFormats =
116        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
117
118    {
119        String8 supportedPreviewFormats;
120        bool addComma = false;
121        for (size_t i=0; i < availableFormats.count; i++) {
122            if (addComma) supportedPreviewFormats += ",";
123            addComma = true;
124            switch (availableFormats.data.i32[i]) {
125            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
126                supportedPreviewFormats +=
127                    CameraParameters::PIXEL_FORMAT_YUV422SP;
128                break;
129            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
130                supportedPreviewFormats +=
131                    CameraParameters::PIXEL_FORMAT_YUV420SP;
132                break;
133            case HAL_PIXEL_FORMAT_YCbCr_422_I:
134                supportedPreviewFormats +=
135                    CameraParameters::PIXEL_FORMAT_YUV422I;
136                break;
137            case HAL_PIXEL_FORMAT_YV12:
138                supportedPreviewFormats +=
139                    CameraParameters::PIXEL_FORMAT_YUV420P;
140                break;
141            case HAL_PIXEL_FORMAT_RGB_565:
142                supportedPreviewFormats +=
143                    CameraParameters::PIXEL_FORMAT_RGB565;
144                break;
145            case HAL_PIXEL_FORMAT_RGBA_8888:
146                supportedPreviewFormats +=
147                    CameraParameters::PIXEL_FORMAT_RGBA8888;
148                break;
149            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
150            case HAL_PIXEL_FORMAT_RAW_SENSOR:
151            case HAL_PIXEL_FORMAT_BLOB:
152                addComma = false;
153                break;
154
155            default:
156                ALOGW("%s: Camera %d: Unknown preview format: %x",
157                        __FUNCTION__, cameraId, availableFormats.data.i32[i]);
158                addComma = false;
159                break;
160            }
161        }
162        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
163                supportedPreviewFormats);
164    }
165
166    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
167    // still have to do something sane for them
168
169    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
170            previewFpsRange[0]);
171
172    {
173        String8 supportedPreviewFrameRates;
174        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
175            if (i != 0) supportedPreviewFrameRates += ",";
176            supportedPreviewFrameRates += String8::format("%d",
177                    availableFpsRanges.data.i32[i]);
178        }
179        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
180                supportedPreviewFrameRates);
181    }
182
183    camera_metadata_ro_entry_t availableJpegSizes =
184        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
185    if (!availableJpegSizes.count) return NO_INIT;
186
187    // TODO: Pick maximum
188    pictureWidth = availableJpegSizes.data.i32[0];
189    pictureHeight = availableJpegSizes.data.i32[1];
190
191    params.setPictureSize(pictureWidth,
192            pictureHeight);
193
194    {
195        String8 supportedPictureSizes;
196        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
197            if (i != 0) supportedPictureSizes += ",";
198            supportedPictureSizes += String8::format("%dx%d",
199                    availableJpegSizes.data.i32[i],
200                    availableJpegSizes.data.i32[i+1]);
201        }
202        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
203                supportedPictureSizes);
204    }
205
206    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
207    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
208            CameraParameters::PIXEL_FORMAT_JPEG);
209
210    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
211        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 4);
212    if (!availableJpegThumbnailSizes.count) return NO_INIT;
213
214    // TODO: Pick default thumbnail size sensibly
215    jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
216    jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
217
218    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
219            jpegThumbSize[0]);
220    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
221            jpegThumbSize[1]);
222
223    {
224        String8 supportedJpegThumbSizes;
225        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
226            if (i != 0) supportedJpegThumbSizes += ",";
227            supportedJpegThumbSizes += String8::format("%dx%d",
228                    availableJpegThumbnailSizes.data.i32[i],
229                    availableJpegThumbnailSizes.data.i32[i+1]);
230        }
231        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
232                supportedJpegThumbSizes);
233    }
234
235    jpegThumbQuality = 90;
236    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
237            jpegThumbQuality);
238    jpegQuality = 90;
239    params.set(CameraParameters::KEY_JPEG_QUALITY,
240            jpegQuality);
241    jpegRotation = 0;
242    params.set(CameraParameters::KEY_ROTATION,
243            jpegRotation);
244
245    gpsEnabled = false;
246    gpsProcessingMethod = "unknown";
247    // GPS fields in CameraParameters are not set by implementation
248
249    wbMode = ANDROID_CONTROL_AWB_AUTO;
250    params.set(CameraParameters::KEY_WHITE_BALANCE,
251            CameraParameters::WHITE_BALANCE_AUTO);
252
253    camera_metadata_ro_entry_t availableWhiteBalanceModes =
254        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
255    {
256        String8 supportedWhiteBalance;
257        bool addComma = false;
258        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
259            if (addComma) supportedWhiteBalance += ",";
260            addComma = true;
261            switch (availableWhiteBalanceModes.data.u8[i]) {
262            case ANDROID_CONTROL_AWB_AUTO:
263                supportedWhiteBalance +=
264                    CameraParameters::WHITE_BALANCE_AUTO;
265                break;
266            case ANDROID_CONTROL_AWB_INCANDESCENT:
267                supportedWhiteBalance +=
268                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
269                break;
270            case ANDROID_CONTROL_AWB_FLUORESCENT:
271                supportedWhiteBalance +=
272                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
273                break;
274            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
275                supportedWhiteBalance +=
276                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
277                break;
278            case ANDROID_CONTROL_AWB_DAYLIGHT:
279                supportedWhiteBalance +=
280                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
281                break;
282            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
283                supportedWhiteBalance +=
284                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
285                break;
286            case ANDROID_CONTROL_AWB_TWILIGHT:
287                supportedWhiteBalance +=
288                    CameraParameters::WHITE_BALANCE_TWILIGHT;
289                break;
290            case ANDROID_CONTROL_AWB_SHADE:
291                supportedWhiteBalance +=
292                    CameraParameters::WHITE_BALANCE_SHADE;
293                break;
294            // Skipping values not mappable to v1 API
295            case ANDROID_CONTROL_AWB_OFF:
296                addComma = false;
297                break;
298            default:
299                ALOGW("%s: Camera %d: Unknown white balance value: %d",
300                        __FUNCTION__, cameraId,
301                        availableWhiteBalanceModes.data.u8[i]);
302                addComma = false;
303                break;
304            }
305        }
306        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
307                supportedWhiteBalance);
308    }
309
310    effectMode = ANDROID_CONTROL_EFFECT_OFF;
311    params.set(CameraParameters::KEY_EFFECT,
312            CameraParameters::EFFECT_NONE);
313
314    camera_metadata_ro_entry_t availableEffects =
315        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
316    if (!availableEffects.count) return NO_INIT;
317    {
318        String8 supportedEffects;
319        bool addComma = false;
320        for (size_t i=0; i < availableEffects.count; i++) {
321            if (addComma) supportedEffects += ",";
322            addComma = true;
323            switch (availableEffects.data.u8[i]) {
324                case ANDROID_CONTROL_EFFECT_OFF:
325                    supportedEffects +=
326                        CameraParameters::EFFECT_NONE;
327                    break;
328                case ANDROID_CONTROL_EFFECT_MONO:
329                    supportedEffects +=
330                        CameraParameters::EFFECT_MONO;
331                    break;
332                case ANDROID_CONTROL_EFFECT_NEGATIVE:
333                    supportedEffects +=
334                        CameraParameters::EFFECT_NEGATIVE;
335                    break;
336                case ANDROID_CONTROL_EFFECT_SOLARIZE:
337                    supportedEffects +=
338                        CameraParameters::EFFECT_SOLARIZE;
339                    break;
340                case ANDROID_CONTROL_EFFECT_SEPIA:
341                    supportedEffects +=
342                        CameraParameters::EFFECT_SEPIA;
343                    break;
344                case ANDROID_CONTROL_EFFECT_POSTERIZE:
345                    supportedEffects +=
346                        CameraParameters::EFFECT_POSTERIZE;
347                    break;
348                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
349                    supportedEffects +=
350                        CameraParameters::EFFECT_WHITEBOARD;
351                    break;
352                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
353                    supportedEffects +=
354                        CameraParameters::EFFECT_BLACKBOARD;
355                    break;
356                case ANDROID_CONTROL_EFFECT_AQUA:
357                    supportedEffects +=
358                        CameraParameters::EFFECT_AQUA;
359                    break;
360                default:
361                    ALOGW("%s: Camera %d: Unknown effect value: %d",
362                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
363                    addComma = false;
364                    break;
365            }
366        }
367        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
368    }
369
370    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
371    params.set(CameraParameters::KEY_ANTIBANDING,
372            CameraParameters::ANTIBANDING_AUTO);
373
374    camera_metadata_ro_entry_t availableAntibandingModes =
375        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
376    if (!availableAntibandingModes.count) return NO_INIT;
377    {
378        String8 supportedAntibanding;
379        bool addComma = false;
380        for (size_t i=0; i < availableAntibandingModes.count; i++) {
381            if (addComma) supportedAntibanding += ",";
382            addComma = true;
383            switch (availableAntibandingModes.data.u8[i]) {
384                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
385                    supportedAntibanding +=
386                        CameraParameters::ANTIBANDING_OFF;
387                    break;
388                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
389                    supportedAntibanding +=
390                        CameraParameters::ANTIBANDING_50HZ;
391                    break;
392                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
393                    supportedAntibanding +=
394                        CameraParameters::ANTIBANDING_60HZ;
395                    break;
396                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
397                    supportedAntibanding +=
398                        CameraParameters::ANTIBANDING_AUTO;
399                    break;
400                default:
401                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
402                        __FUNCTION__, cameraId,
403                            availableAntibandingModes.data.u8[i]);
404                    addComma = false;
405                    break;
406            }
407        }
408        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
409                supportedAntibanding);
410    }
411
412    sceneMode = ANDROID_CONTROL_OFF;
413    params.set(CameraParameters::KEY_SCENE_MODE,
414            CameraParameters::SCENE_MODE_AUTO);
415
416    camera_metadata_ro_entry_t availableSceneModes =
417        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
418    if (!availableSceneModes.count) return NO_INIT;
419    {
420        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
421        bool addComma = true;
422        bool noSceneModes = false;
423        for (size_t i=0; i < availableSceneModes.count; i++) {
424            if (addComma) supportedSceneModes += ",";
425            addComma = true;
426            switch (availableSceneModes.data.u8[i]) {
427                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
428                    noSceneModes = true;
429                    break;
430                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
431                    // Not in old API
432                    addComma = false;
433                    break;
434                case ANDROID_CONTROL_SCENE_MODE_ACTION:
435                    supportedSceneModes +=
436                        CameraParameters::SCENE_MODE_ACTION;
437                    break;
438                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
439                    supportedSceneModes +=
440                        CameraParameters::SCENE_MODE_PORTRAIT;
441                    break;
442                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
443                    supportedSceneModes +=
444                        CameraParameters::SCENE_MODE_LANDSCAPE;
445                    break;
446                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
447                    supportedSceneModes +=
448                        CameraParameters::SCENE_MODE_NIGHT;
449                    break;
450                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
451                    supportedSceneModes +=
452                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
453                    break;
454                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
455                    supportedSceneModes +=
456                        CameraParameters::SCENE_MODE_THEATRE;
457                    break;
458                case ANDROID_CONTROL_SCENE_MODE_BEACH:
459                    supportedSceneModes +=
460                        CameraParameters::SCENE_MODE_BEACH;
461                    break;
462                case ANDROID_CONTROL_SCENE_MODE_SNOW:
463                    supportedSceneModes +=
464                        CameraParameters::SCENE_MODE_SNOW;
465                    break;
466                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
467                    supportedSceneModes +=
468                        CameraParameters::SCENE_MODE_SUNSET;
469                    break;
470                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
471                    supportedSceneModes +=
472                        CameraParameters::SCENE_MODE_STEADYPHOTO;
473                    break;
474                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
475                    supportedSceneModes +=
476                        CameraParameters::SCENE_MODE_FIREWORKS;
477                    break;
478                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
479                    supportedSceneModes +=
480                        CameraParameters::SCENE_MODE_SPORTS;
481                    break;
482                case ANDROID_CONTROL_SCENE_MODE_PARTY:
483                    supportedSceneModes +=
484                        CameraParameters::SCENE_MODE_PARTY;
485                    break;
486                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
487                    supportedSceneModes +=
488                        CameraParameters::SCENE_MODE_CANDLELIGHT;
489                    break;
490                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
491                    supportedSceneModes +=
492                        CameraParameters::SCENE_MODE_BARCODE;
493                    break;
494                default:
495                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
496                        __FUNCTION__, cameraId,
497                            availableSceneModes.data.u8[i]);
498                    addComma = false;
499                    break;
500            }
501        }
502        if (!noSceneModes) {
503            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
504                    supportedSceneModes);
505        }
506    }
507
508    camera_metadata_ro_entry_t flashAvailable =
509        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
510    if (!flashAvailable.count) return NO_INIT;
511
512    camera_metadata_ro_entry_t availableAeModes =
513        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
514    if (!availableAeModes.count) return NO_INIT;
515
516    if (flashAvailable.data.u8[0]) {
517        flashMode = Parameters::FLASH_MODE_AUTO;
518        params.set(CameraParameters::KEY_FLASH_MODE,
519                CameraParameters::FLASH_MODE_AUTO);
520
521        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
522        supportedFlashModes = supportedFlashModes +
523            "," + CameraParameters::FLASH_MODE_AUTO +
524            "," + CameraParameters::FLASH_MODE_ON +
525            "," + CameraParameters::FLASH_MODE_TORCH;
526        for (size_t i=0; i < availableAeModes.count; i++) {
527            if (availableAeModes.data.u8[i] ==
528                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
529                supportedFlashModes = supportedFlashModes + "," +
530                    CameraParameters::FLASH_MODE_RED_EYE;
531                break;
532            }
533        }
534        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
535                supportedFlashModes);
536    } else {
537        flashMode = Parameters::FLASH_MODE_OFF;
538        params.set(CameraParameters::KEY_FLASH_MODE,
539                CameraParameters::FLASH_MODE_OFF);
540        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
541                CameraParameters::FLASH_MODE_OFF);
542    }
543
544    camera_metadata_ro_entry_t minFocusDistance =
545        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
546    if (!minFocusDistance.count) return NO_INIT;
547
548    camera_metadata_ro_entry_t availableAfModes =
549        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
550    if (!availableAfModes.count) return NO_INIT;
551
552    if (minFocusDistance.data.f[0] == 0) {
553        // Fixed-focus lens
554        focusMode = Parameters::FOCUS_MODE_FIXED;
555        params.set(CameraParameters::KEY_FOCUS_MODE,
556                CameraParameters::FOCUS_MODE_FIXED);
557        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
558                CameraParameters::FOCUS_MODE_FIXED);
559    } else {
560        focusMode = Parameters::FOCUS_MODE_AUTO;
561        params.set(CameraParameters::KEY_FOCUS_MODE,
562                CameraParameters::FOCUS_MODE_AUTO);
563        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
564        bool addComma = true;
565
566        for (size_t i=0; i < availableAfModes.count; i++) {
567            if (addComma) supportedFocusModes += ",";
568            addComma = true;
569            switch (availableAfModes.data.u8[i]) {
570                case ANDROID_CONTROL_AF_AUTO:
571                    supportedFocusModes +=
572                        CameraParameters::FOCUS_MODE_AUTO;
573                    break;
574                case ANDROID_CONTROL_AF_MACRO:
575                    supportedFocusModes +=
576                        CameraParameters::FOCUS_MODE_MACRO;
577                    break;
578                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
579                    supportedFocusModes +=
580                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
581                    break;
582                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
583                    supportedFocusModes +=
584                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
585                    break;
586                case ANDROID_CONTROL_AF_EDOF:
587                    supportedFocusModes +=
588                        CameraParameters::FOCUS_MODE_EDOF;
589                    break;
590                // Not supported in old API
591                case ANDROID_CONTROL_AF_OFF:
592                    addComma = false;
593                    break;
594                default:
595                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
596                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
597                    addComma = false;
598                    break;
599            }
600        }
601        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
602                supportedFocusModes);
603    }
604
605    camera_metadata_ro_entry_t max3aRegions =
606        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
607    if (!max3aRegions.count) return NO_INIT;
608
609    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
610            max3aRegions.data.i32[0]);
611    params.set(CameraParameters::KEY_FOCUS_AREAS,
612            "(0,0,0,0,0)");
613    focusingAreas.clear();
614    focusingAreas.add(Parameters::Area(0,0,0,0,0));
615
616    camera_metadata_ro_entry_t availableFocalLengths =
617        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
618    if (!availableFocalLengths.count) return NO_INIT;
619
620    float minFocalLength = availableFocalLengths.data.f[0];
621    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
622
623    camera_metadata_ro_entry_t sensorSize =
624        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
625    if (!sensorSize.count) return NO_INIT;
626
627    // The fields of view here assume infinity focus, maximum wide angle
628    float horizFov = 180 / M_PI *
629            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
630    float vertFov  = 180 / M_PI *
631            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
632    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
633    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
634
635    exposureCompensation = 0;
636    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
637                exposureCompensation);
638
639    camera_metadata_ro_entry_t exposureCompensationRange =
640        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
641    if (!exposureCompensationRange.count) return NO_INIT;
642
643    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
644            exposureCompensationRange.data.i32[1]);
645    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
646            exposureCompensationRange.data.i32[0]);
647
648    camera_metadata_ro_entry_t exposureCompensationStep =
649        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
650    if (!exposureCompensationStep.count) return NO_INIT;
651
652    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
653            (float)exposureCompensationStep.data.r[0].numerator /
654            exposureCompensationStep.data.r[0].denominator);
655
656    autoExposureLock = false;
657    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
658            CameraParameters::FALSE);
659    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
660            CameraParameters::TRUE);
661
662    autoWhiteBalanceLock = false;
663    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
664            CameraParameters::FALSE);
665    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
666            CameraParameters::TRUE);
667
668    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
669    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
670            max3aRegions.data.i32[0]);
671    params.set(CameraParameters::KEY_METERING_AREAS,
672            "(0,0,0,0,0)");
673
674    zoom = 0;
675    params.set(CameraParameters::KEY_ZOOM, zoom);
676    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
677
678    camera_metadata_ro_entry_t maxDigitalZoom =
679        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
680    if (!maxDigitalZoom.count) return NO_INIT;
681
682    {
683        String8 zoomRatios;
684        float zoom = 1.f;
685        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
686                (NUM_ZOOM_STEPS-1);
687        bool addComma = false;
688        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
689            if (addComma) zoomRatios += ",";
690            addComma = true;
691            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
692            zoom += zoomIncrement;
693        }
694        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
695    }
696
697    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
698            CameraParameters::TRUE);
699    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
700            CameraParameters::TRUE);
701
702    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
703            "Infinity,Infinity,Infinity");
704
705    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
706            fastInfo.maxFaces);
707    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
708            0);
709
710    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
711            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
712
713    params.set(CameraParameters::KEY_RECORDING_HINT,
714            CameraParameters::FALSE);
715
716    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
717            CameraParameters::TRUE);
718
719    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
720            CameraParameters::FALSE);
721
722    camera_metadata_ro_entry_t availableVideoStabilizationModes =
723        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
724    if (!availableVideoStabilizationModes.count) return NO_INIT;
725
726    if (availableVideoStabilizationModes.count > 1) {
727        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
728                CameraParameters::TRUE);
729    } else {
730        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
731                CameraParameters::FALSE);
732    }
733
734    // Set up initial state for non-Camera.Parameters state variables
735
736    storeMetadataInBuffers = true;
737    playShutterSound = true;
738    enableFaceDetect = false;
739
740    enableFocusMoveMessages = false;
741    afTriggerCounter = 0;
742    currentAfTriggerId = -1;
743
744    previewCallbackFlags = 0;
745
746    state = STOPPED;
747
748    paramsFlattened = params.flatten();
749
750    return OK;
751}
752
753status_t Parameters::buildFastInfo() {
754
755    camera_metadata_ro_entry_t activeArraySize =
756        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
757    if (!activeArraySize.count) return NO_INIT;
758    int32_t arrayWidth = activeArraySize.data.i32[0];
759    int32_t arrayHeight = activeArraySize.data.i32[1];
760
761    camera_metadata_ro_entry_t availableFaceDetectModes =
762        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
763    if (!availableFaceDetectModes.count) return NO_INIT;
764
765    uint8_t bestFaceDetectMode =
766        ANDROID_STATS_FACE_DETECTION_OFF;
767    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
768        switch (availableFaceDetectModes.data.u8[i]) {
769            case ANDROID_STATS_FACE_DETECTION_OFF:
770                break;
771            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
772                if (bestFaceDetectMode !=
773                        ANDROID_STATS_FACE_DETECTION_FULL) {
774                    bestFaceDetectMode =
775                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
776                }
777                break;
778            case ANDROID_STATS_FACE_DETECTION_FULL:
779                bestFaceDetectMode =
780                    ANDROID_STATS_FACE_DETECTION_FULL;
781                break;
782            default:
783                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
784                        __FUNCTION__, cameraId,
785                        availableFaceDetectModes.data.u8[i]);
786                return NO_INIT;
787        }
788    }
789
790    camera_metadata_ro_entry_t maxFacesDetected =
791        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
792    if (!maxFacesDetected.count) return NO_INIT;
793
794    int32_t maxFaces = maxFacesDetected.data.i32[0];
795
796    fastInfo.arrayWidth = arrayWidth;
797    fastInfo.arrayHeight = arrayHeight;
798    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
799    fastInfo.maxFaces = maxFaces;
800    return OK;
801}
802
803camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
804        size_t minCount, size_t maxCount) const {
805    status_t res;
806    camera_metadata_ro_entry_t entry = info->find(tag);
807
808    if (CC_UNLIKELY( entry.count == 0 )) {
809        const char* tagSection = get_camera_metadata_section_name(tag);
810        if (tagSection == NULL) tagSection = "<unknown>";
811        const char* tagName = get_camera_metadata_tag_name(tag);
812        if (tagName == NULL) tagName = "<unknown>";
813
814        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
815                tagSection, tagName, tag);
816    } else if (CC_UNLIKELY(
817            (minCount != 0 && entry.count < minCount) ||
818            (maxCount != 0 && entry.count > maxCount) ) ) {
819        const char* tagSection = get_camera_metadata_section_name(tag);
820        if (tagSection == NULL) tagSection = "<unknown>";
821        const char* tagName = get_camera_metadata_tag_name(tag);
822        if (tagName == NULL) tagName = "<unknown>";
823        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
824                "Expected between %d and %d values, but got %d values",
825                tagSection, tagName, tag, minCount, maxCount, entry.count);
826    }
827
828    return entry;
829}
830
831status_t Parameters::set(const String8& params) {
832    status_t res;
833
834    CameraParameters newParams(params);
835
836    // TODO: Currently ignoring any changes to supposedly read-only parameters
837    // such as supported preview sizes, etc. Should probably produce an error if
838    // they're changed.
839
840    /** Extract and verify new parameters */
841
842    size_t i;
843
844    Parameters validatedParams(*this);
845
846    // PREVIEW_SIZE
847    newParams.getPreviewSize(&validatedParams.previewWidth,
848            &validatedParams.previewHeight);
849
850    if (validatedParams.previewWidth != previewWidth ||
851            validatedParams.previewHeight != previewHeight) {
852        if (state >= PREVIEW) {
853            ALOGE("%s: Preview size cannot be updated when preview "
854                    "is active! (Currently %d x %d, requested %d x %d",
855                    __FUNCTION__,
856                    previewWidth, previewHeight,
857                    validatedParams.previewWidth, validatedParams.previewHeight);
858            return BAD_VALUE;
859        }
860        camera_metadata_ro_entry_t availablePreviewSizes =
861            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
862        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
863            if ((availablePreviewSizes.data.i32[i] ==
864                    validatedParams.previewWidth) &&
865                (availablePreviewSizes.data.i32[i+1] ==
866                    validatedParams.previewHeight)) break;
867        }
868        if (i == availablePreviewSizes.count) {
869            ALOGE("%s: Requested preview size %d x %d is not supported",
870                    __FUNCTION__, validatedParams.previewWidth,
871                    validatedParams.previewHeight);
872            return BAD_VALUE;
873        }
874    }
875
876    // PREVIEW_FPS_RANGE
877    bool fpsRangeChanged = false;
878    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
879            &validatedParams.previewFpsRange[1]);
880    if (validatedParams.previewFpsRange[0] != previewFpsRange[0] ||
881            validatedParams.previewFpsRange[1] != previewFpsRange[1]) {
882        fpsRangeChanged = true;
883        camera_metadata_ro_entry_t availablePreviewFpsRanges =
884            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
885        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
886            if ((availablePreviewFpsRanges.data.i32[i] ==
887                    validatedParams.previewFpsRange[0]) &&
888                (availablePreviewFpsRanges.data.i32[i+1] ==
889                    validatedParams.previewFpsRange[1]) ) {
890                break;
891            }
892        }
893        if (i == availablePreviewFpsRanges.count) {
894            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
895                __FUNCTION__, validatedParams.previewFpsRange[0],
896                    validatedParams.previewFpsRange[1]);
897            return BAD_VALUE;
898        }
899        validatedParams.previewFps = validatedParams.previewFpsRange[0];
900    }
901
902    // PREVIEW_FORMAT
903    validatedParams.previewFormat =
904            formatStringToEnum(newParams.getPreviewFormat());
905    if (validatedParams.previewFormat != previewFormat) {
906        if (state >= PREVIEW) {
907            ALOGE("%s: Preview format cannot be updated when preview "
908                    "is active!", __FUNCTION__);
909            return BAD_VALUE;
910        }
911        camera_metadata_ro_entry_t availableFormats =
912            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
913        for (i = 0; i < availableFormats.count; i++) {
914            if (availableFormats.data.i32[i] == validatedParams.previewFormat)
915                break;
916        }
917        if (i == availableFormats.count) {
918            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
919                    __FUNCTION__, newParams.getPreviewFormat(),
920                    validatedParams.previewFormat);
921            return BAD_VALUE;
922        }
923    }
924
925    // PREVIEW_FRAME_RATE
926    // Deprecated, only use if the preview fps range is unchanged this time.
927    // The single-value FPS is the same as the minimum of the range.
928    if (!fpsRangeChanged) {
929        validatedParams.previewFps = newParams.getPreviewFrameRate();
930        if (validatedParams.previewFps != previewFps) {
931            camera_metadata_ro_entry_t availableFrameRates =
932                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
933            for (i = 0; i < availableFrameRates.count; i+=2) {
934                if (availableFrameRates.data.i32[i] ==
935                        validatedParams.previewFps) break;
936            }
937            if (i == availableFrameRates.count) {
938                ALOGE("%s: Requested preview frame rate %d is not supported",
939                        __FUNCTION__, validatedParams.previewFps);
940                return BAD_VALUE;
941            }
942            validatedParams.previewFpsRange[0] =
943                    availableFrameRates.data.i32[i];
944            validatedParams.previewFpsRange[1] =
945                    availableFrameRates.data.i32[i+1];
946        }
947    }
948
949    // PICTURE_SIZE
950    newParams.getPictureSize(&validatedParams.pictureWidth,
951            &validatedParams.pictureHeight);
952    if (validatedParams.pictureWidth == pictureWidth ||
953            validatedParams.pictureHeight == pictureHeight) {
954        camera_metadata_ro_entry_t availablePictureSizes =
955            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
956        for (i = 0; i < availablePictureSizes.count; i+=2) {
957            if ((availablePictureSizes.data.i32[i] ==
958                    validatedParams.pictureWidth) &&
959                (availablePictureSizes.data.i32[i+1] ==
960                    validatedParams.pictureHeight)) break;
961        }
962        if (i == availablePictureSizes.count) {
963            ALOGE("%s: Requested picture size %d x %d is not supported",
964                    __FUNCTION__, validatedParams.pictureWidth,
965                    validatedParams.pictureHeight);
966            return BAD_VALUE;
967        }
968    }
969
970    // JPEG_THUMBNAIL_WIDTH/HEIGHT
971    validatedParams.jpegThumbSize[0] =
972            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
973    validatedParams.jpegThumbSize[1] =
974            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
975    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
976            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
977        camera_metadata_ro_entry_t availableJpegThumbSizes =
978            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
979        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
980            if ((availableJpegThumbSizes.data.i32[i] ==
981                    validatedParams.jpegThumbSize[0]) &&
982                (availableJpegThumbSizes.data.i32[i+1] ==
983                    validatedParams.jpegThumbSize[1])) break;
984        }
985        if (i == availableJpegThumbSizes.count) {
986            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
987                    __FUNCTION__, validatedParams.jpegThumbSize[0],
988                    validatedParams.jpegThumbSize[1]);
989            return BAD_VALUE;
990        }
991    }
992
993    // JPEG_THUMBNAIL_QUALITY
994    validatedParams.jpegThumbQuality =
995            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
996    if (validatedParams.jpegThumbQuality < 0 ||
997            validatedParams.jpegThumbQuality > 100) {
998        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
999                __FUNCTION__, validatedParams.jpegThumbQuality);
1000        return BAD_VALUE;
1001    }
1002
1003    // JPEG_QUALITY
1004    validatedParams.jpegQuality =
1005            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1006    if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
1007        ALOGE("%s: Requested JPEG quality %d is not supported",
1008                __FUNCTION__, validatedParams.jpegQuality);
1009        return BAD_VALUE;
1010    }
1011
1012    // ROTATION
1013    validatedParams.jpegRotation =
1014            newParams.getInt(CameraParameters::KEY_ROTATION);
1015    if (validatedParams.jpegRotation != 0 &&
1016            validatedParams.jpegRotation != 90 &&
1017            validatedParams.jpegRotation != 180 &&
1018            validatedParams.jpegRotation != 270) {
1019        ALOGE("%s: Requested picture rotation angle %d is not supported",
1020                __FUNCTION__, validatedParams.jpegRotation);
1021        return BAD_VALUE;
1022    }
1023
1024    // GPS
1025
1026    const char *gpsLatStr =
1027            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1028    if (gpsLatStr != NULL) {
1029        const char *gpsLongStr =
1030                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1031        const char *gpsAltitudeStr =
1032                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1033        const char *gpsTimeStr =
1034                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1035        const char *gpsProcMethodStr =
1036                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1037        if (gpsLongStr == NULL ||
1038                gpsAltitudeStr == NULL ||
1039                gpsTimeStr == NULL ||
1040                gpsProcMethodStr == NULL) {
1041            ALOGE("%s: Incomplete set of GPS parameters provided",
1042                    __FUNCTION__);
1043            return BAD_VALUE;
1044        }
1045        char *endPtr;
1046        errno = 0;
1047        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1048        if (errno || endPtr == gpsLatStr) {
1049            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1050            return BAD_VALUE;
1051        }
1052        errno = 0;
1053        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1054        if (errno || endPtr == gpsLongStr) {
1055            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1056            return BAD_VALUE;
1057        }
1058        errno = 0;
1059        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1060        if (errno || endPtr == gpsAltitudeStr) {
1061            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1062                    gpsAltitudeStr);
1063            return BAD_VALUE;
1064        }
1065        errno = 0;
1066        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1067        if (errno || endPtr == gpsTimeStr) {
1068            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1069            return BAD_VALUE;
1070        }
1071        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1072
1073        validatedParams.gpsEnabled = true;
1074    } else {
1075        validatedParams.gpsEnabled = false;
1076    }
1077
1078    // WHITE_BALANCE
1079    validatedParams.wbMode = wbModeStringToEnum(
1080        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1081    if (validatedParams.wbMode != wbMode) {
1082        camera_metadata_ro_entry_t availableWbModes =
1083            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1084        for (i = 0; i < availableWbModes.count; i++) {
1085            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1086        }
1087        if (i == availableWbModes.count) {
1088            ALOGE("%s: Requested white balance mode %s is not supported",
1089                    __FUNCTION__,
1090                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1091            return BAD_VALUE;
1092        }
1093    }
1094
1095    // EFFECT
1096    validatedParams.effectMode = effectModeStringToEnum(
1097        newParams.get(CameraParameters::KEY_EFFECT) );
1098    if (validatedParams.effectMode != effectMode) {
1099        camera_metadata_ro_entry_t availableEffectModes =
1100            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1101        for (i = 0; i < availableEffectModes.count; i++) {
1102            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1103        }
1104        if (i == availableEffectModes.count) {
1105            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1106                    __FUNCTION__,
1107                    newParams.get(CameraParameters::KEY_EFFECT) );
1108            return BAD_VALUE;
1109        }
1110    }
1111
1112    // ANTIBANDING
1113    validatedParams.antibandingMode = abModeStringToEnum(
1114        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1115    if (validatedParams.antibandingMode != antibandingMode) {
1116        camera_metadata_ro_entry_t availableAbModes =
1117            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1118        for (i = 0; i < availableAbModes.count; i++) {
1119            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1120                break;
1121        }
1122        if (i == availableAbModes.count) {
1123            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1124                    __FUNCTION__,
1125                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1126            return BAD_VALUE;
1127        }
1128    }
1129
1130    // SCENE_MODE
1131    validatedParams.sceneMode = sceneModeStringToEnum(
1132        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1133    if (validatedParams.sceneMode != sceneMode &&
1134            validatedParams.sceneMode !=
1135            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1136        camera_metadata_ro_entry_t availableSceneModes =
1137            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1138        for (i = 0; i < availableSceneModes.count; i++) {
1139            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1140                break;
1141        }
1142        if (i == availableSceneModes.count) {
1143            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1144                    __FUNCTION__,
1145                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1146            return BAD_VALUE;
1147        }
1148    }
1149
1150    // FLASH_MODE
1151    validatedParams.flashMode = flashModeStringToEnum(
1152        newParams.get(CameraParameters::KEY_FLASH_MODE) );
1153    if (validatedParams.flashMode != flashMode) {
1154        camera_metadata_ro_entry_t flashAvailable =
1155            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1156        if (!flashAvailable.data.u8[0] &&
1157                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1158            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1159                    "No flash on device", __FUNCTION__,
1160                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1161            return BAD_VALUE;
1162        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1163            camera_metadata_ro_entry_t availableAeModes =
1164                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1165            for (i = 0; i < availableAeModes.count; i++) {
1166                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1167                    break;
1168            }
1169            if (i == availableAeModes.count) {
1170                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1171                        __FUNCTION__,
1172                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1173                return BAD_VALUE;
1174            }
1175        } else if (validatedParams.flashMode == -1) {
1176            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1177                    __FUNCTION__,
1178                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1179            return BAD_VALUE;
1180        }
1181    }
1182
1183    // FOCUS_MODE
1184    validatedParams.focusMode = focusModeStringToEnum(
1185        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1186    if (validatedParams.focusMode != focusMode) {
1187        validatedParams.currentAfTriggerId = -1;
1188        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1189            camera_metadata_ro_entry_t minFocusDistance =
1190                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1191            if (minFocusDistance.data.f[0] == 0) {
1192                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1193                        "fixed focus lens",
1194                        __FUNCTION__,
1195                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1196                return BAD_VALUE;
1197            } else if (validatedParams.focusMode !=
1198                    Parameters::FOCUS_MODE_INFINITY) {
1199                camera_metadata_ro_entry_t availableFocusModes =
1200                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1201                for (i = 0; i < availableFocusModes.count; i++) {
1202                    if (validatedParams.focusMode ==
1203                            availableFocusModes.data.u8[i]) break;
1204                }
1205                if (i == availableFocusModes.count) {
1206                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1207                            __FUNCTION__,
1208                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1209                    return BAD_VALUE;
1210                }
1211            }
1212        }
1213    } else {
1214        validatedParams.currentAfTriggerId = currentAfTriggerId;
1215    }
1216
1217    // FOCUS_AREAS
1218    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1219            &validatedParams.focusingAreas);
1220    size_t max3aRegions =
1221        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1222    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1223            max3aRegions);
1224    if (res != OK) {
1225        ALOGE("%s: Requested focus areas are malformed: %s",
1226                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1227        return BAD_VALUE;
1228    }
1229
1230    // EXPOSURE_COMPENSATION
1231    validatedParams.exposureCompensation =
1232        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1233    camera_metadata_ro_entry_t exposureCompensationRange =
1234        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1235    if ((validatedParams.exposureCompensation <
1236            exposureCompensationRange.data.i32[0]) ||
1237        (validatedParams.exposureCompensation >
1238            exposureCompensationRange.data.i32[1])) {
1239        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1240                __FUNCTION__, validatedParams.exposureCompensation);
1241        return BAD_VALUE;
1242    }
1243
1244    // AUTO_EXPOSURE_LOCK (always supported)
1245    validatedParams.autoExposureLock = boolFromString(
1246        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1247
1248    // AUTO_WHITEBALANCE_LOCK (always supported)
1249    validatedParams.autoWhiteBalanceLock = boolFromString(
1250        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1251
1252    // METERING_AREAS
1253    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1254            &validatedParams.meteringAreas);
1255    if (res == OK) {
1256        res = validateAreas(validatedParams.meteringAreas, max3aRegions);
1257    }
1258    if (res != OK) {
1259        ALOGE("%s: Requested metering areas are malformed: %s",
1260                __FUNCTION__,
1261                newParams.get(CameraParameters::KEY_METERING_AREAS));
1262        return BAD_VALUE;
1263    }
1264
1265    // ZOOM
1266    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1267    if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
1268        ALOGE("%s: Requested zoom level %d is not supported",
1269                __FUNCTION__, validatedParams.zoom);
1270        return BAD_VALUE;
1271    }
1272
1273    // VIDEO_SIZE
1274    newParams.getVideoSize(&validatedParams.videoWidth,
1275            &validatedParams.videoHeight);
1276    if (validatedParams.videoWidth != videoWidth ||
1277            validatedParams.videoHeight != videoHeight) {
1278        if (state == RECORD) {
1279            ALOGE("%s: Video size cannot be updated when recording is active!",
1280                    __FUNCTION__);
1281            return BAD_VALUE;
1282        }
1283        camera_metadata_ro_entry_t availableVideoSizes =
1284            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1285        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1286            if ((availableVideoSizes.data.i32[i] ==
1287                    validatedParams.videoWidth) &&
1288                (availableVideoSizes.data.i32[i+1] ==
1289                    validatedParams.videoHeight)) break;
1290        }
1291        if (i == availableVideoSizes.count) {
1292            ALOGE("%s: Requested video size %d x %d is not supported",
1293                    __FUNCTION__, validatedParams.videoWidth,
1294                    validatedParams.videoHeight);
1295            return BAD_VALUE;
1296        }
1297    }
1298
1299    // RECORDING_HINT (always supported)
1300    validatedParams.recordingHint = boolFromString(
1301        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1302
1303    // VIDEO_STABILIZATION
1304    validatedParams.videoStabilization = boolFromString(
1305        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1306    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1307        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1308    if (validatedParams.videoStabilization &&
1309            availableVideoStabilizationModes.count == 1) {
1310        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1311    }
1312
1313    /** Update internal parameters */
1314
1315    validatedParams.paramsFlattened = params;
1316    *this = validatedParams;
1317
1318    return OK;
1319}
1320
1321const char* Parameters::getStateName(State state) {
1322#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1323    switch(state) {
1324        CASE_ENUM_TO_CHAR(DISCONNECTED)
1325        CASE_ENUM_TO_CHAR(STOPPED)
1326        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1327        CASE_ENUM_TO_CHAR(PREVIEW)
1328        CASE_ENUM_TO_CHAR(RECORD)
1329        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
1330        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
1331        default:
1332            return "Unknown state!";
1333            break;
1334    }
1335#undef CASE_ENUM_TO_CHAR
1336}
1337
1338int Parameters::formatStringToEnum(const char *format) {
1339    return
1340        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
1341            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
1342        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
1343            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
1344        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
1345            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
1346        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
1347            HAL_PIXEL_FORMAT_YV12 :         // YV12
1348        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
1349            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
1350        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
1351            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
1352        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
1353            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
1354        -1;
1355}
1356
1357const char* Parameters::formatEnumToString(int format) {
1358    const char *fmt;
1359    switch(format) {
1360        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1361            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
1362            break;
1363        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1364            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
1365            break;
1366        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1367            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
1368            break;
1369        case HAL_PIXEL_FORMAT_YV12:        // YV12
1370            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
1371            break;
1372        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
1373            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
1374            break;
1375        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
1376            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
1377            break;
1378        case HAL_PIXEL_FORMAT_RAW_SENSOR:
1379            ALOGW("Raw sensor preview format requested.");
1380            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
1381            break;
1382        default:
1383            ALOGE("%s: Unknown preview format: %x",
1384                    __FUNCTION__,  format);
1385            fmt = NULL;
1386            break;
1387    }
1388    return fmt;
1389}
1390
1391int Parameters::wbModeStringToEnum(const char *wbMode) {
1392    return
1393        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
1394            ANDROID_CONTROL_AWB_AUTO :
1395        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
1396            ANDROID_CONTROL_AWB_INCANDESCENT :
1397        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
1398            ANDROID_CONTROL_AWB_FLUORESCENT :
1399        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
1400            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
1401        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
1402            ANDROID_CONTROL_AWB_DAYLIGHT :
1403        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
1404            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
1405        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
1406            ANDROID_CONTROL_AWB_TWILIGHT :
1407        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
1408            ANDROID_CONTROL_AWB_SHADE :
1409        -1;
1410}
1411
1412int Parameters::effectModeStringToEnum(const char *effectMode) {
1413    return
1414        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
1415            ANDROID_CONTROL_EFFECT_OFF :
1416        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
1417            ANDROID_CONTROL_EFFECT_MONO :
1418        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
1419            ANDROID_CONTROL_EFFECT_NEGATIVE :
1420        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
1421            ANDROID_CONTROL_EFFECT_SOLARIZE :
1422        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
1423            ANDROID_CONTROL_EFFECT_SEPIA :
1424        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
1425            ANDROID_CONTROL_EFFECT_POSTERIZE :
1426        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
1427            ANDROID_CONTROL_EFFECT_WHITEBOARD :
1428        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
1429            ANDROID_CONTROL_EFFECT_BLACKBOARD :
1430        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
1431            ANDROID_CONTROL_EFFECT_AQUA :
1432        -1;
1433}
1434
1435int Parameters::abModeStringToEnum(const char *abMode) {
1436    return
1437        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
1438            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1439        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
1440            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
1441        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
1442            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
1443        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
1444            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
1445        -1;
1446}
1447
1448int Parameters::sceneModeStringToEnum(const char *sceneMode) {
1449    return
1450        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
1451            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1452        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
1453            ANDROID_CONTROL_SCENE_MODE_ACTION :
1454        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
1455            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
1456        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
1457            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
1458        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
1459            ANDROID_CONTROL_SCENE_MODE_NIGHT :
1460        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
1461            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
1462        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
1463            ANDROID_CONTROL_SCENE_MODE_THEATRE :
1464        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
1465            ANDROID_CONTROL_SCENE_MODE_BEACH :
1466        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
1467            ANDROID_CONTROL_SCENE_MODE_SNOW :
1468        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
1469            ANDROID_CONTROL_SCENE_MODE_SUNSET :
1470        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
1471            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
1472        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
1473            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
1474        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
1475            ANDROID_CONTROL_SCENE_MODE_SPORTS :
1476        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
1477            ANDROID_CONTROL_SCENE_MODE_PARTY :
1478        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
1479            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
1480        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
1481            ANDROID_CONTROL_SCENE_MODE_BARCODE:
1482        -1;
1483}
1484
1485Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
1486        const char *flashMode) {
1487    return
1488        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
1489            Parameters::FLASH_MODE_OFF :
1490        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
1491            Parameters::FLASH_MODE_AUTO :
1492        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
1493            Parameters::FLASH_MODE_ON :
1494        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
1495            Parameters::FLASH_MODE_RED_EYE :
1496        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
1497            Parameters::FLASH_MODE_TORCH :
1498        Parameters::FLASH_MODE_INVALID;
1499}
1500
1501Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
1502        const char *focusMode) {
1503    return
1504        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
1505            Parameters::FOCUS_MODE_AUTO :
1506        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
1507            Parameters::FOCUS_MODE_INFINITY :
1508        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
1509            Parameters::FOCUS_MODE_MACRO :
1510        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
1511            Parameters::FOCUS_MODE_FIXED :
1512        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
1513            Parameters::FOCUS_MODE_EDOF :
1514        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
1515            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
1516        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
1517            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
1518        Parameters::FOCUS_MODE_INVALID;
1519}
1520
1521status_t Parameters::parseAreas(const char *areasCStr,
1522        Vector<Parameters::Area> *areas) {
1523    static const size_t NUM_FIELDS = 5;
1524    areas->clear();
1525    if (areasCStr == NULL) {
1526        // If no key exists, use default (0,0,0,0,0)
1527        areas->push();
1528        return OK;
1529    }
1530    String8 areasStr(areasCStr);
1531    ssize_t areaStart = areasStr.find("(", 0) + 1;
1532    while (areaStart != 0) {
1533        const char* area = areasStr.string() + areaStart;
1534        char *numEnd;
1535        int vals[NUM_FIELDS];
1536        for (size_t i = 0; i < NUM_FIELDS; i++) {
1537            errno = 0;
1538            vals[i] = strtol(area, &numEnd, 10);
1539            if (errno || numEnd == area) return BAD_VALUE;
1540            area = numEnd + 1;
1541        }
1542        areas->push(Parameters::Area(
1543            vals[0], vals[1], vals[2], vals[3], vals[4]) );
1544        areaStart = areasStr.find("(", areaStart) + 1;
1545    }
1546    return OK;
1547}
1548
1549status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
1550                                      size_t maxRegions) {
1551    // Definition of valid area can be found in
1552    // include/camera/CameraParameters.h
1553    if (areas.size() == 0) return BAD_VALUE;
1554    if (areas.size() == 1) {
1555        if (areas[0].left == 0 &&
1556                areas[0].top == 0 &&
1557                areas[0].right == 0 &&
1558                areas[0].bottom == 0 &&
1559                areas[0].weight == 0) {
1560            // Single (0,0,0,0,0) entry is always valid (== driver decides)
1561            return OK;
1562        }
1563    }
1564    if (areas.size() > maxRegions) {
1565        ALOGE("%s: Too many areas requested: %d",
1566                __FUNCTION__, areas.size());
1567        return BAD_VALUE;
1568    }
1569
1570    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
1571         a != areas.end(); a++) {
1572        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
1573        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
1574        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
1575        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
1576        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
1577        if (a->left >= a->right) return BAD_VALUE;
1578        if (a->top >= a->bottom) return BAD_VALUE;
1579    }
1580    return OK;
1581}
1582
1583bool Parameters::boolFromString(const char *boolStr) {
1584    return !boolStr ? false :
1585        !strcmp(boolStr, CameraParameters::TRUE) ? true :
1586        false;
1587}
1588
1589int Parameters::degToTransform(int degrees, bool mirror) {
1590    if (!mirror) {
1591        if (degrees == 0) return 0;
1592        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
1593        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
1594        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1595    } else {  // Do mirror (horizontal flip)
1596        if (degrees == 0) {           // FLIP_H and ROT_0
1597            return HAL_TRANSFORM_FLIP_H;
1598        } else if (degrees == 90) {   // FLIP_H and ROT_90
1599            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1600        } else if (degrees == 180) {  // FLIP_H and ROT_180
1601            return HAL_TRANSFORM_FLIP_V;
1602        } else if (degrees == 270) {  // FLIP_H and ROT_270
1603            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1604        }
1605    }
1606    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
1607    return -1;
1608}
1609
1610int Parameters::arrayXToNormalized(int width) const {
1611    return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
1612}
1613
1614int Parameters::arrayYToNormalized(int height) const {
1615    return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
1616}
1617
1618int Parameters::normalizedXToArray(int x) const {
1619    return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
1620}
1621
1622int Parameters::normalizedYToArray(int y) const {
1623    return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
1624}
1625
1626}; // namespace camera2
1627}; // namespace android
1628