Parameters.cpp revision 95069fefbdf54d87a624c2ac73727fce1c38545e
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
24#include <math.h>
25#include <stdlib.h>
26#include <cutils/properties.h>
27
28#include "Parameters.h"
29#include "system/camera.h"
30
31namespace android {
32namespace camera2 {
33
34Parameters::Parameters(int cameraId,
35        int cameraFacing) :
36        cameraId(cameraId),
37        cameraFacing(cameraFacing),
38        info(NULL) {
39}
40
41Parameters::~Parameters() {
42}
43
44status_t Parameters::initialize(const CameraMetadata *info) {
45    status_t res;
46
47    if (info->entryCount() == 0) {
48        ALOGE("%s: No static information provided!", __FUNCTION__);
49        return BAD_VALUE;
50    }
51    Parameters::info = info;
52
53    res = buildFastInfo();
54    if (res != OK) return res;
55
56    res = buildQuirks();
57    if (res != OK) return res;
58
59    camera_metadata_ro_entry_t availableProcessedSizes =
60        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
61    if (!availableProcessedSizes.count) return NO_INIT;
62
63    // TODO: Pick more intelligently
64    previewWidth = availableProcessedSizes.data.i32[0];
65    previewHeight = availableProcessedSizes.data.i32[1];
66    videoWidth = previewWidth;
67    videoHeight = previewHeight;
68
69    params.setPreviewSize(previewWidth, previewHeight);
70    params.setVideoSize(videoWidth, videoHeight);
71    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
72            String8::format("%dx%d",
73                    previewWidth, previewHeight));
74    {
75        String8 supportedPreviewSizes;
76        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
77            if (i != 0) supportedPreviewSizes += ",";
78            supportedPreviewSizes += String8::format("%dx%d",
79                    availableProcessedSizes.data.i32[i],
80                    availableProcessedSizes.data.i32[i+1]);
81        }
82        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
83                supportedPreviewSizes);
84        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
85                supportedPreviewSizes);
86    }
87
88    camera_metadata_ro_entry_t availableFpsRanges =
89        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
90    if (!availableFpsRanges.count) return NO_INIT;
91
92    previewFpsRange[0] = availableFpsRanges.data.i32[0];
93    previewFpsRange[1] = availableFpsRanges.data.i32[1];
94
95    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
96            String8::format("%d,%d",
97                    previewFpsRange[0] * kFpsToApiScale,
98                    previewFpsRange[1] * kFpsToApiScale));
99
100    {
101        String8 supportedPreviewFpsRange;
102        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
103            if (i != 0) supportedPreviewFpsRange += ",";
104            supportedPreviewFpsRange += String8::format("(%d,%d)",
105                    availableFpsRanges.data.i32[i] * kFpsToApiScale,
106                    availableFpsRanges.data.i32[i+1] * kFpsToApiScale);
107        }
108        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
109                supportedPreviewFpsRange);
110    }
111
112    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
113    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
114            formatEnumToString(previewFormat)); // NV21
115
116    previewTransform = degToTransform(0,
117            cameraFacing == CAMERA_FACING_FRONT);
118
119    camera_metadata_ro_entry_t availableFormats =
120        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
121
122    {
123        String8 supportedPreviewFormats;
124        bool addComma = false;
125        for (size_t i=0; i < availableFormats.count; i++) {
126            if (addComma) supportedPreviewFormats += ",";
127            addComma = true;
128            switch (availableFormats.data.i32[i]) {
129            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
130                supportedPreviewFormats +=
131                    CameraParameters::PIXEL_FORMAT_YUV422SP;
132                break;
133            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
134                supportedPreviewFormats +=
135                    CameraParameters::PIXEL_FORMAT_YUV420SP;
136                break;
137            case HAL_PIXEL_FORMAT_YCbCr_422_I:
138                supportedPreviewFormats +=
139                    CameraParameters::PIXEL_FORMAT_YUV422I;
140                break;
141            case HAL_PIXEL_FORMAT_YV12:
142                supportedPreviewFormats +=
143                    CameraParameters::PIXEL_FORMAT_YUV420P;
144                break;
145            case HAL_PIXEL_FORMAT_RGB_565:
146                supportedPreviewFormats +=
147                    CameraParameters::PIXEL_FORMAT_RGB565;
148                break;
149            case HAL_PIXEL_FORMAT_RGBA_8888:
150                supportedPreviewFormats +=
151                    CameraParameters::PIXEL_FORMAT_RGBA8888;
152                break;
153            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
154            case HAL_PIXEL_FORMAT_RAW_SENSOR:
155            case HAL_PIXEL_FORMAT_BLOB:
156                addComma = false;
157                break;
158
159            default:
160                ALOGW("%s: Camera %d: Unknown preview format: %x",
161                        __FUNCTION__, cameraId, availableFormats.data.i32[i]);
162                addComma = false;
163                break;
164            }
165        }
166        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
167                supportedPreviewFormats);
168    }
169
170    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
171    // still have to do something sane for them
172
173    // NOTE: Not scaled like FPS range values are.
174    previewFps = previewFpsRange[0];
175    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
176            previewFpsRange[0]);
177
178    {
179        String8 supportedPreviewFrameRates;
180        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
181            if (i != 0) supportedPreviewFrameRates += ",";
182            supportedPreviewFrameRates += String8::format("%d",
183                    availableFpsRanges.data.i32[i]);
184        }
185        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
186                supportedPreviewFrameRates);
187    }
188
189    camera_metadata_ro_entry_t availableJpegSizes =
190        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
191    if (!availableJpegSizes.count) return NO_INIT;
192
193    // TODO: Pick maximum
194    pictureWidth = availableJpegSizes.data.i32[0];
195    pictureHeight = availableJpegSizes.data.i32[1];
196
197    params.setPictureSize(pictureWidth,
198            pictureHeight);
199
200    {
201        String8 supportedPictureSizes;
202        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
203            if (i != 0) supportedPictureSizes += ",";
204            supportedPictureSizes += String8::format("%dx%d",
205                    availableJpegSizes.data.i32[i],
206                    availableJpegSizes.data.i32[i+1]);
207        }
208        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
209                supportedPictureSizes);
210    }
211
212    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
213    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
214            CameraParameters::PIXEL_FORMAT_JPEG);
215
216    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
217        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 4);
218    if (!availableJpegThumbnailSizes.count) return NO_INIT;
219
220    // TODO: Pick default thumbnail size sensibly
221    jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
222    jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
223
224    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
225            jpegThumbSize[0]);
226    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
227            jpegThumbSize[1]);
228
229    {
230        String8 supportedJpegThumbSizes;
231        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
232            if (i != 0) supportedJpegThumbSizes += ",";
233            supportedJpegThumbSizes += String8::format("%dx%d",
234                    availableJpegThumbnailSizes.data.i32[i],
235                    availableJpegThumbnailSizes.data.i32[i+1]);
236        }
237        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
238                supportedJpegThumbSizes);
239    }
240
241    jpegThumbQuality = 90;
242    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
243            jpegThumbQuality);
244    jpegQuality = 90;
245    params.set(CameraParameters::KEY_JPEG_QUALITY,
246            jpegQuality);
247    jpegRotation = 0;
248    params.set(CameraParameters::KEY_ROTATION,
249            jpegRotation);
250
251    gpsEnabled = false;
252    gpsProcessingMethod = "unknown";
253    // GPS fields in CameraParameters are not set by implementation
254
255    wbMode = ANDROID_CONTROL_AWB_AUTO;
256    params.set(CameraParameters::KEY_WHITE_BALANCE,
257            CameraParameters::WHITE_BALANCE_AUTO);
258
259    camera_metadata_ro_entry_t availableWhiteBalanceModes =
260        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
261    {
262        String8 supportedWhiteBalance;
263        bool addComma = false;
264        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
265            if (addComma) supportedWhiteBalance += ",";
266            addComma = true;
267            switch (availableWhiteBalanceModes.data.u8[i]) {
268            case ANDROID_CONTROL_AWB_AUTO:
269                supportedWhiteBalance +=
270                    CameraParameters::WHITE_BALANCE_AUTO;
271                break;
272            case ANDROID_CONTROL_AWB_INCANDESCENT:
273                supportedWhiteBalance +=
274                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
275                break;
276            case ANDROID_CONTROL_AWB_FLUORESCENT:
277                supportedWhiteBalance +=
278                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
279                break;
280            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
281                supportedWhiteBalance +=
282                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
283                break;
284            case ANDROID_CONTROL_AWB_DAYLIGHT:
285                supportedWhiteBalance +=
286                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
287                break;
288            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
289                supportedWhiteBalance +=
290                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
291                break;
292            case ANDROID_CONTROL_AWB_TWILIGHT:
293                supportedWhiteBalance +=
294                    CameraParameters::WHITE_BALANCE_TWILIGHT;
295                break;
296            case ANDROID_CONTROL_AWB_SHADE:
297                supportedWhiteBalance +=
298                    CameraParameters::WHITE_BALANCE_SHADE;
299                break;
300            // Skipping values not mappable to v1 API
301            case ANDROID_CONTROL_AWB_OFF:
302                addComma = false;
303                break;
304            default:
305                ALOGW("%s: Camera %d: Unknown white balance value: %d",
306                        __FUNCTION__, cameraId,
307                        availableWhiteBalanceModes.data.u8[i]);
308                addComma = false;
309                break;
310            }
311        }
312        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
313                supportedWhiteBalance);
314    }
315
316    effectMode = ANDROID_CONTROL_EFFECT_OFF;
317    params.set(CameraParameters::KEY_EFFECT,
318            CameraParameters::EFFECT_NONE);
319
320    camera_metadata_ro_entry_t availableEffects =
321        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
322    if (!availableEffects.count) return NO_INIT;
323    {
324        String8 supportedEffects;
325        bool addComma = false;
326        for (size_t i=0; i < availableEffects.count; i++) {
327            if (addComma) supportedEffects += ",";
328            addComma = true;
329            switch (availableEffects.data.u8[i]) {
330                case ANDROID_CONTROL_EFFECT_OFF:
331                    supportedEffects +=
332                        CameraParameters::EFFECT_NONE;
333                    break;
334                case ANDROID_CONTROL_EFFECT_MONO:
335                    supportedEffects +=
336                        CameraParameters::EFFECT_MONO;
337                    break;
338                case ANDROID_CONTROL_EFFECT_NEGATIVE:
339                    supportedEffects +=
340                        CameraParameters::EFFECT_NEGATIVE;
341                    break;
342                case ANDROID_CONTROL_EFFECT_SOLARIZE:
343                    supportedEffects +=
344                        CameraParameters::EFFECT_SOLARIZE;
345                    break;
346                case ANDROID_CONTROL_EFFECT_SEPIA:
347                    supportedEffects +=
348                        CameraParameters::EFFECT_SEPIA;
349                    break;
350                case ANDROID_CONTROL_EFFECT_POSTERIZE:
351                    supportedEffects +=
352                        CameraParameters::EFFECT_POSTERIZE;
353                    break;
354                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
355                    supportedEffects +=
356                        CameraParameters::EFFECT_WHITEBOARD;
357                    break;
358                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
359                    supportedEffects +=
360                        CameraParameters::EFFECT_BLACKBOARD;
361                    break;
362                case ANDROID_CONTROL_EFFECT_AQUA:
363                    supportedEffects +=
364                        CameraParameters::EFFECT_AQUA;
365                    break;
366                default:
367                    ALOGW("%s: Camera %d: Unknown effect value: %d",
368                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
369                    addComma = false;
370                    break;
371            }
372        }
373        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
374    }
375
376    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
377    params.set(CameraParameters::KEY_ANTIBANDING,
378            CameraParameters::ANTIBANDING_AUTO);
379
380    camera_metadata_ro_entry_t availableAntibandingModes =
381        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
382    if (!availableAntibandingModes.count) return NO_INIT;
383    {
384        String8 supportedAntibanding;
385        bool addComma = false;
386        for (size_t i=0; i < availableAntibandingModes.count; i++) {
387            if (addComma) supportedAntibanding += ",";
388            addComma = true;
389            switch (availableAntibandingModes.data.u8[i]) {
390                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
391                    supportedAntibanding +=
392                        CameraParameters::ANTIBANDING_OFF;
393                    break;
394                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
395                    supportedAntibanding +=
396                        CameraParameters::ANTIBANDING_50HZ;
397                    break;
398                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
399                    supportedAntibanding +=
400                        CameraParameters::ANTIBANDING_60HZ;
401                    break;
402                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
403                    supportedAntibanding +=
404                        CameraParameters::ANTIBANDING_AUTO;
405                    break;
406                default:
407                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
408                        __FUNCTION__, cameraId,
409                            availableAntibandingModes.data.u8[i]);
410                    addComma = false;
411                    break;
412            }
413        }
414        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
415                supportedAntibanding);
416    }
417
418    sceneMode = ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
419    params.set(CameraParameters::KEY_SCENE_MODE,
420            CameraParameters::SCENE_MODE_AUTO);
421
422    camera_metadata_ro_entry_t availableSceneModes =
423        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
424    if (!availableSceneModes.count) return NO_INIT;
425    {
426        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
427        bool addComma = true;
428        bool noSceneModes = false;
429        for (size_t i=0; i < availableSceneModes.count; i++) {
430            if (addComma) supportedSceneModes += ",";
431            addComma = true;
432            switch (availableSceneModes.data.u8[i]) {
433                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
434                    noSceneModes = true;
435                    break;
436                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
437                    // Not in old API
438                    addComma = false;
439                    break;
440                case ANDROID_CONTROL_SCENE_MODE_ACTION:
441                    supportedSceneModes +=
442                        CameraParameters::SCENE_MODE_ACTION;
443                    break;
444                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
445                    supportedSceneModes +=
446                        CameraParameters::SCENE_MODE_PORTRAIT;
447                    break;
448                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
449                    supportedSceneModes +=
450                        CameraParameters::SCENE_MODE_LANDSCAPE;
451                    break;
452                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
453                    supportedSceneModes +=
454                        CameraParameters::SCENE_MODE_NIGHT;
455                    break;
456                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
457                    supportedSceneModes +=
458                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
459                    break;
460                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
461                    supportedSceneModes +=
462                        CameraParameters::SCENE_MODE_THEATRE;
463                    break;
464                case ANDROID_CONTROL_SCENE_MODE_BEACH:
465                    supportedSceneModes +=
466                        CameraParameters::SCENE_MODE_BEACH;
467                    break;
468                case ANDROID_CONTROL_SCENE_MODE_SNOW:
469                    supportedSceneModes +=
470                        CameraParameters::SCENE_MODE_SNOW;
471                    break;
472                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
473                    supportedSceneModes +=
474                        CameraParameters::SCENE_MODE_SUNSET;
475                    break;
476                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
477                    supportedSceneModes +=
478                        CameraParameters::SCENE_MODE_STEADYPHOTO;
479                    break;
480                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
481                    supportedSceneModes +=
482                        CameraParameters::SCENE_MODE_FIREWORKS;
483                    break;
484                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
485                    supportedSceneModes +=
486                        CameraParameters::SCENE_MODE_SPORTS;
487                    break;
488                case ANDROID_CONTROL_SCENE_MODE_PARTY:
489                    supportedSceneModes +=
490                        CameraParameters::SCENE_MODE_PARTY;
491                    break;
492                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
493                    supportedSceneModes +=
494                        CameraParameters::SCENE_MODE_CANDLELIGHT;
495                    break;
496                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
497                    supportedSceneModes +=
498                        CameraParameters::SCENE_MODE_BARCODE;
499                    break;
500                default:
501                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
502                        __FUNCTION__, cameraId,
503                            availableSceneModes.data.u8[i]);
504                    addComma = false;
505                    break;
506            }
507        }
508        if (!noSceneModes) {
509            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
510                    supportedSceneModes);
511        }
512    }
513
514    camera_metadata_ro_entry_t flashAvailable =
515        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
516    if (!flashAvailable.count) return NO_INIT;
517
518    camera_metadata_ro_entry_t availableAeModes =
519        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
520    if (!availableAeModes.count) return NO_INIT;
521
522    if (flashAvailable.data.u8[0]) {
523        flashMode = Parameters::FLASH_MODE_AUTO;
524        params.set(CameraParameters::KEY_FLASH_MODE,
525                CameraParameters::FLASH_MODE_AUTO);
526
527        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
528        supportedFlashModes = supportedFlashModes +
529            "," + CameraParameters::FLASH_MODE_AUTO +
530            "," + CameraParameters::FLASH_MODE_ON +
531            "," + CameraParameters::FLASH_MODE_TORCH;
532        for (size_t i=0; i < availableAeModes.count; i++) {
533            if (availableAeModes.data.u8[i] ==
534                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
535                supportedFlashModes = supportedFlashModes + "," +
536                    CameraParameters::FLASH_MODE_RED_EYE;
537                break;
538            }
539        }
540        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
541                supportedFlashModes);
542    } else {
543        flashMode = Parameters::FLASH_MODE_OFF;
544        params.set(CameraParameters::KEY_FLASH_MODE,
545                CameraParameters::FLASH_MODE_OFF);
546        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
547                CameraParameters::FLASH_MODE_OFF);
548    }
549
550    camera_metadata_ro_entry_t minFocusDistance =
551        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
552    if (!minFocusDistance.count) return NO_INIT;
553
554    camera_metadata_ro_entry_t availableAfModes =
555        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
556    if (!availableAfModes.count) return NO_INIT;
557
558    if (minFocusDistance.data.f[0] == 0) {
559        // Fixed-focus lens
560        focusMode = Parameters::FOCUS_MODE_FIXED;
561        params.set(CameraParameters::KEY_FOCUS_MODE,
562                CameraParameters::FOCUS_MODE_FIXED);
563        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
564                CameraParameters::FOCUS_MODE_FIXED);
565    } else {
566        focusMode = Parameters::FOCUS_MODE_AUTO;
567        params.set(CameraParameters::KEY_FOCUS_MODE,
568                CameraParameters::FOCUS_MODE_AUTO);
569        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
570        bool addComma = true;
571
572        for (size_t i=0; i < availableAfModes.count; i++) {
573            if (addComma) supportedFocusModes += ",";
574            addComma = true;
575            switch (availableAfModes.data.u8[i]) {
576                case ANDROID_CONTROL_AF_AUTO:
577                    supportedFocusModes +=
578                        CameraParameters::FOCUS_MODE_AUTO;
579                    break;
580                case ANDROID_CONTROL_AF_MACRO:
581                    supportedFocusModes +=
582                        CameraParameters::FOCUS_MODE_MACRO;
583                    break;
584                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
585                    supportedFocusModes +=
586                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
587                    break;
588                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
589                    supportedFocusModes +=
590                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
591                    break;
592                case ANDROID_CONTROL_AF_EDOF:
593                    supportedFocusModes +=
594                        CameraParameters::FOCUS_MODE_EDOF;
595                    break;
596                // Not supported in old API
597                case ANDROID_CONTROL_AF_OFF:
598                    addComma = false;
599                    break;
600                default:
601                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
602                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
603                    addComma = false;
604                    break;
605            }
606        }
607        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
608                supportedFocusModes);
609    }
610    shadowFocusMode = FOCUS_MODE_INVALID;
611
612    camera_metadata_ro_entry_t max3aRegions =
613        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
614    if (!max3aRegions.count) return NO_INIT;
615
616    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
617            max3aRegions.data.i32[0]);
618    params.set(CameraParameters::KEY_FOCUS_AREAS,
619            "(0,0,0,0,0)");
620    focusingAreas.clear();
621    focusingAreas.add(Parameters::Area(0,0,0,0,0));
622
623    camera_metadata_ro_entry_t availableFocalLengths =
624        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
625    if (!availableFocalLengths.count) return NO_INIT;
626
627    float minFocalLength = availableFocalLengths.data.f[0];
628    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
629
630    camera_metadata_ro_entry_t sensorSize =
631        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
632    if (!sensorSize.count) return NO_INIT;
633
634    // The fields of view here assume infinity focus, maximum wide angle
635    float horizFov = 180 / M_PI *
636            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
637    float vertFov  = 180 / M_PI *
638            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
639    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
640    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
641
642    exposureCompensation = 0;
643    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
644                exposureCompensation);
645
646    camera_metadata_ro_entry_t exposureCompensationRange =
647        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
648    if (!exposureCompensationRange.count) return NO_INIT;
649
650    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
651            exposureCompensationRange.data.i32[1]);
652    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
653            exposureCompensationRange.data.i32[0]);
654
655    camera_metadata_ro_entry_t exposureCompensationStep =
656        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
657    if (!exposureCompensationStep.count) return NO_INIT;
658
659    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
660            (float)exposureCompensationStep.data.r[0].numerator /
661            exposureCompensationStep.data.r[0].denominator);
662
663    autoExposureLock = false;
664    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
665            CameraParameters::FALSE);
666    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
667            CameraParameters::TRUE);
668
669    autoWhiteBalanceLock = false;
670    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
671            CameraParameters::FALSE);
672    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
673            CameraParameters::TRUE);
674
675    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
676    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
677            max3aRegions.data.i32[0]);
678    params.set(CameraParameters::KEY_METERING_AREAS,
679            "(0,0,0,0,0)");
680
681    zoom = 0;
682    params.set(CameraParameters::KEY_ZOOM, zoom);
683    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
684
685    camera_metadata_ro_entry_t maxDigitalZoom =
686        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, /*minCount*/1, /*maxCount*/1);
687    if (!maxDigitalZoom.count) return NO_INIT;
688
689    {
690        String8 zoomRatios;
691        float zoom = 1.f;
692        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
693                (NUM_ZOOM_STEPS-1);
694        bool addComma = false;
695        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
696            if (addComma) zoomRatios += ",";
697            addComma = true;
698            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
699            zoom += zoomIncrement;
700        }
701        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
702    }
703
704    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
705            CameraParameters::TRUE);
706    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
707            CameraParameters::TRUE);
708
709    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
710            "Infinity,Infinity,Infinity");
711
712    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
713            fastInfo.maxFaces);
714    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
715            0);
716
717    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
718            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
719
720    params.set(CameraParameters::KEY_RECORDING_HINT,
721            CameraParameters::FALSE);
722
723    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
724            CameraParameters::TRUE);
725
726    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
727            CameraParameters::FALSE);
728
729    camera_metadata_ro_entry_t availableVideoStabilizationModes =
730        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
731    if (!availableVideoStabilizationModes.count) return NO_INIT;
732
733    if (availableVideoStabilizationModes.count > 1) {
734        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
735                CameraParameters::TRUE);
736    } else {
737        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
738                CameraParameters::FALSE);
739    }
740
741    // Set up initial state for non-Camera.Parameters state variables
742
743    storeMetadataInBuffers = true;
744    playShutterSound = true;
745    enableFaceDetect = false;
746
747    enableFocusMoveMessages = false;
748    afTriggerCounter = 1;
749    currentAfTriggerId = -1;
750
751    precaptureTriggerCounter = 1;
752
753    previewCallbackFlags = 0;
754
755    char value[PROPERTY_VALUE_MAX];
756    property_get("camera.disable_zsl_mode", value, "0");
757    if (!strcmp(value,"1")) {
758        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
759        zslMode = false;
760    } else {
761        zslMode = true;
762    }
763
764    lightFx = LIGHTFX_NONE;
765
766    state = STOPPED;
767
768    paramsFlattened = params.flatten();
769
770    return OK;
771}
772
773String8 Parameters::get() const {
774    return paramsFlattened;
775}
776
777status_t Parameters::buildFastInfo() {
778
779    camera_metadata_ro_entry_t activeArraySize =
780        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
781    if (!activeArraySize.count) return NO_INIT;
782    int32_t arrayWidth = activeArraySize.data.i32[0];
783    int32_t arrayHeight = activeArraySize.data.i32[1];
784
785    camera_metadata_ro_entry_t availableFaceDetectModes =
786        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
787    if (!availableFaceDetectModes.count) return NO_INIT;
788
789    uint8_t bestFaceDetectMode =
790        ANDROID_STATS_FACE_DETECTION_OFF;
791    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
792        switch (availableFaceDetectModes.data.u8[i]) {
793            case ANDROID_STATS_FACE_DETECTION_OFF:
794                break;
795            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
796                if (bestFaceDetectMode !=
797                        ANDROID_STATS_FACE_DETECTION_FULL) {
798                    bestFaceDetectMode =
799                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
800                }
801                break;
802            case ANDROID_STATS_FACE_DETECTION_FULL:
803                bestFaceDetectMode =
804                    ANDROID_STATS_FACE_DETECTION_FULL;
805                break;
806            default:
807                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
808                        __FUNCTION__, cameraId,
809                        availableFaceDetectModes.data.u8[i]);
810                return NO_INIT;
811        }
812    }
813
814    camera_metadata_ro_entry_t maxFacesDetected =
815        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
816    if (!maxFacesDetected.count) return NO_INIT;
817
818    int32_t maxFaces = maxFacesDetected.data.i32[0];
819
820    camera_metadata_ro_entry_t availableSceneModes =
821        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
822    camera_metadata_ro_entry_t sceneModeOverrides =
823        staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES);
824    camera_metadata_ro_entry_t minFocusDistance =
825        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
826    bool fixedLens = (minFocusDistance.data.f[0] == 0);
827
828    if (sceneModeOverrides.count > 0) {
829        // sceneModeOverrides is defined to have 3 entries for each scene mode,
830        // which are AE, AWB, and AF override modes the HAL wants for that scene
831        // mode.
832        const size_t kModesPerSceneMode = 3;
833        if (sceneModeOverrides.count !=
834                availableSceneModes.count * kModesPerSceneMode) {
835            ALOGE("%s: Camera %d: Scene mode override list is an "
836                    "unexpected size: %d (expected %d)", __FUNCTION__,
837                    cameraId, sceneModeOverrides.count,
838                    availableSceneModes.count);
839            return NO_INIT;
840        }
841        for (size_t i = 0; i < availableSceneModes.count; i++) {
842            DeviceInfo::OverrideModes modes;
843            uint8_t aeMode =
844                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
845            switch(aeMode) {
846                case ANDROID_CONTROL_AE_ON:
847                    modes.flashMode = FLASH_MODE_OFF;
848                    break;
849                case ANDROID_CONTROL_AE_ON_AUTO_FLASH:
850                    modes.flashMode = FLASH_MODE_AUTO;
851                    break;
852                case ANDROID_CONTROL_AE_ON_ALWAYS_FLASH:
853                    modes.flashMode = FLASH_MODE_ON;
854                    break;
855                case ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE:
856                    modes.flashMode = FLASH_MODE_RED_EYE;
857                    break;
858                default:
859                    ALOGE("%s: Unknown override AE mode: %d", __FUNCTION__,
860                            aeMode);
861                    modes.flashMode = FLASH_MODE_INVALID;
862                    break;
863            }
864            modes.wbMode =
865                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 1];
866            uint8_t afMode =
867                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
868            switch(afMode) {
869                case ANDROID_CONTROL_AF_OFF:
870                    modes.focusMode = fixedLens ?
871                            FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
872                    break;
873                case ANDROID_CONTROL_AF_AUTO:
874                case ANDROID_CONTROL_AF_MACRO:
875                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
876                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
877                case ANDROID_CONTROL_AF_EDOF:
878                    modes.focusMode = static_cast<focusMode_t>(afMode);
879                    break;
880                default:
881                    ALOGE("%s: Unknown override AF mode: %d", __FUNCTION__,
882                            afMode);
883                    modes.focusMode = FOCUS_MODE_INVALID;
884                    break;
885            }
886            fastInfo.sceneModeOverrides.add(availableSceneModes.data.u8[i],
887                    modes);
888        }
889    }
890
891    fastInfo.arrayWidth = arrayWidth;
892    fastInfo.arrayHeight = arrayHeight;
893    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
894    fastInfo.maxFaces = maxFaces;
895    return OK;
896}
897
898status_t Parameters::buildQuirks() {
899    camera_metadata_ro_entry_t entry;
900    entry = info->find(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO);
901    quirks.triggerAfWithAuto = (entry.count != 0 && entry.data.u8[0] == 1);
902    ALOGV_IF(quirks.triggerAfWithAuto, "Camera %d: Quirk triggerAfWithAuto enabled",
903            cameraId);
904
905    entry = info->find(ANDROID_QUIRKS_USE_ZSL_FORMAT);
906    quirks.useZslFormat = (entry.count != 0 && entry.data.u8[0] == 1);
907    ALOGV_IF(quirks.useZslFormat, "Camera %d: Quirk useZslFormat enabled",
908            cameraId);
909
910    return OK;
911}
912
913camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
914        size_t minCount, size_t maxCount) const {
915    status_t res;
916    camera_metadata_ro_entry_t entry = info->find(tag);
917
918    if (CC_UNLIKELY( entry.count == 0 )) {
919        const char* tagSection = get_camera_metadata_section_name(tag);
920        if (tagSection == NULL) tagSection = "<unknown>";
921        const char* tagName = get_camera_metadata_tag_name(tag);
922        if (tagName == NULL) tagName = "<unknown>";
923
924        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
925                tagSection, tagName, tag);
926    } else if (CC_UNLIKELY(
927            (minCount != 0 && entry.count < minCount) ||
928            (maxCount != 0 && entry.count > maxCount) ) ) {
929        const char* tagSection = get_camera_metadata_section_name(tag);
930        if (tagSection == NULL) tagSection = "<unknown>";
931        const char* tagName = get_camera_metadata_tag_name(tag);
932        if (tagName == NULL) tagName = "<unknown>";
933        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
934                "Expected between %d and %d values, but got %d values",
935                tagSection, tagName, tag, minCount, maxCount, entry.count);
936    }
937
938    return entry;
939}
940
941status_t Parameters::set(const String8& paramString) {
942    status_t res;
943
944    CameraParameters newParams(paramString);
945
946    // TODO: Currently ignoring any changes to supposedly read-only parameters
947    // such as supported preview sizes, etc. Should probably produce an error if
948    // they're changed.
949
950    /** Extract and verify new parameters */
951
952    size_t i;
953
954    Parameters validatedParams(*this);
955
956    // PREVIEW_SIZE
957    newParams.getPreviewSize(&validatedParams.previewWidth,
958            &validatedParams.previewHeight);
959
960    if (validatedParams.previewWidth != previewWidth ||
961            validatedParams.previewHeight != previewHeight) {
962        if (state >= PREVIEW) {
963            ALOGE("%s: Preview size cannot be updated when preview "
964                    "is active! (Currently %d x %d, requested %d x %d",
965                    __FUNCTION__,
966                    previewWidth, previewHeight,
967                    validatedParams.previewWidth, validatedParams.previewHeight);
968            return BAD_VALUE;
969        }
970        camera_metadata_ro_entry_t availablePreviewSizes =
971            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
972        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
973            if ((availablePreviewSizes.data.i32[i] ==
974                    validatedParams.previewWidth) &&
975                (availablePreviewSizes.data.i32[i+1] ==
976                    validatedParams.previewHeight)) break;
977        }
978        if (i == availablePreviewSizes.count) {
979            ALOGE("%s: Requested preview size %d x %d is not supported",
980                    __FUNCTION__, validatedParams.previewWidth,
981                    validatedParams.previewHeight);
982            return BAD_VALUE;
983        }
984    }
985
986    // PREVIEW_FPS_RANGE
987    bool fpsRangeChanged = false;
988    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
989            &validatedParams.previewFpsRange[1]);
990    validatedParams.previewFpsRange[0] /= kFpsToApiScale;
991    validatedParams.previewFpsRange[1] /= kFpsToApiScale;
992
993    if (validatedParams.previewFpsRange[0] != previewFpsRange[0] ||
994            validatedParams.previewFpsRange[1] != previewFpsRange[1]) {
995        fpsRangeChanged = true;
996        camera_metadata_ro_entry_t availablePreviewFpsRanges =
997            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
998        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
999            if ((availablePreviewFpsRanges.data.i32[i] ==
1000                    validatedParams.previewFpsRange[0]) &&
1001                (availablePreviewFpsRanges.data.i32[i+1] ==
1002                    validatedParams.previewFpsRange[1]) ) {
1003                break;
1004            }
1005        }
1006        if (i == availablePreviewFpsRanges.count) {
1007            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
1008                __FUNCTION__, validatedParams.previewFpsRange[0],
1009                    validatedParams.previewFpsRange[1]);
1010            return BAD_VALUE;
1011        }
1012        validatedParams.previewFps = validatedParams.previewFpsRange[0];
1013        newParams.setPreviewFrameRate(validatedParams.previewFps);
1014    }
1015
1016    // PREVIEW_FORMAT
1017    validatedParams.previewFormat =
1018            formatStringToEnum(newParams.getPreviewFormat());
1019    if (validatedParams.previewFormat != previewFormat) {
1020        if (state >= PREVIEW) {
1021            ALOGE("%s: Preview format cannot be updated when preview "
1022                    "is active!", __FUNCTION__);
1023            return BAD_VALUE;
1024        }
1025        camera_metadata_ro_entry_t availableFormats =
1026            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1027        for (i = 0; i < availableFormats.count; i++) {
1028            if (availableFormats.data.i32[i] == validatedParams.previewFormat)
1029                break;
1030        }
1031        if (i == availableFormats.count) {
1032            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1033                    __FUNCTION__, newParams.getPreviewFormat(),
1034                    validatedParams.previewFormat);
1035            return BAD_VALUE;
1036        }
1037    }
1038
1039    // PREVIEW_FRAME_RATE
1040    // Deprecated, only use if the preview fps range is unchanged this time.
1041    // The single-value FPS is the same as the minimum of the range.
1042    if (!fpsRangeChanged) {
1043        validatedParams.previewFps = newParams.getPreviewFrameRate();
1044        if (validatedParams.previewFps != previewFps) {
1045            camera_metadata_ro_entry_t availableFrameRates =
1046                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1047            for (i = 0; i < availableFrameRates.count; i+=2) {
1048                if (availableFrameRates.data.i32[i] ==
1049                        validatedParams.previewFps) break;
1050            }
1051            if (i == availableFrameRates.count) {
1052                ALOGE("%s: Requested preview frame rate %d is not supported",
1053                        __FUNCTION__, validatedParams.previewFps);
1054                return BAD_VALUE;
1055            }
1056            validatedParams.previewFpsRange[0] =
1057                    availableFrameRates.data.i32[i];
1058            validatedParams.previewFpsRange[1] =
1059                    availableFrameRates.data.i32[i+1];
1060        }
1061        newParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1062                String8::format("%d,%d",
1063                        validatedParams.previewFpsRange[0] * kFpsToApiScale,
1064                        validatedParams.previewFpsRange[1] * kFpsToApiScale));
1065    }
1066
1067    // PICTURE_SIZE
1068    newParams.getPictureSize(&validatedParams.pictureWidth,
1069            &validatedParams.pictureHeight);
1070    if (validatedParams.pictureWidth == pictureWidth ||
1071            validatedParams.pictureHeight == pictureHeight) {
1072        camera_metadata_ro_entry_t availablePictureSizes =
1073            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1074        for (i = 0; i < availablePictureSizes.count; i+=2) {
1075            if ((availablePictureSizes.data.i32[i] ==
1076                    validatedParams.pictureWidth) &&
1077                (availablePictureSizes.data.i32[i+1] ==
1078                    validatedParams.pictureHeight)) break;
1079        }
1080        if (i == availablePictureSizes.count) {
1081            ALOGE("%s: Requested picture size %d x %d is not supported",
1082                    __FUNCTION__, validatedParams.pictureWidth,
1083                    validatedParams.pictureHeight);
1084            return BAD_VALUE;
1085        }
1086    }
1087
1088    // JPEG_THUMBNAIL_WIDTH/HEIGHT
1089    validatedParams.jpegThumbSize[0] =
1090            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1091    validatedParams.jpegThumbSize[1] =
1092            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1093    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
1094            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
1095        camera_metadata_ro_entry_t availableJpegThumbSizes =
1096            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1097        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1098            if ((availableJpegThumbSizes.data.i32[i] ==
1099                    validatedParams.jpegThumbSize[0]) &&
1100                (availableJpegThumbSizes.data.i32[i+1] ==
1101                    validatedParams.jpegThumbSize[1])) break;
1102        }
1103        if (i == availableJpegThumbSizes.count) {
1104            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1105                    __FUNCTION__, validatedParams.jpegThumbSize[0],
1106                    validatedParams.jpegThumbSize[1]);
1107            return BAD_VALUE;
1108        }
1109    }
1110
1111    // JPEG_THUMBNAIL_QUALITY
1112    validatedParams.jpegThumbQuality =
1113            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1114    if (validatedParams.jpegThumbQuality < 0 ||
1115            validatedParams.jpegThumbQuality > 100) {
1116        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1117                __FUNCTION__, validatedParams.jpegThumbQuality);
1118        return BAD_VALUE;
1119    }
1120
1121    // JPEG_QUALITY
1122    validatedParams.jpegQuality =
1123            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1124    if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
1125        ALOGE("%s: Requested JPEG quality %d is not supported",
1126                __FUNCTION__, validatedParams.jpegQuality);
1127        return BAD_VALUE;
1128    }
1129
1130    // ROTATION
1131    validatedParams.jpegRotation =
1132            newParams.getInt(CameraParameters::KEY_ROTATION);
1133    if (validatedParams.jpegRotation != 0 &&
1134            validatedParams.jpegRotation != 90 &&
1135            validatedParams.jpegRotation != 180 &&
1136            validatedParams.jpegRotation != 270) {
1137        ALOGE("%s: Requested picture rotation angle %d is not supported",
1138                __FUNCTION__, validatedParams.jpegRotation);
1139        return BAD_VALUE;
1140    }
1141
1142    // GPS
1143
1144    const char *gpsLatStr =
1145            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1146    if (gpsLatStr != NULL) {
1147        const char *gpsLongStr =
1148                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1149        const char *gpsAltitudeStr =
1150                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1151        const char *gpsTimeStr =
1152                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1153        const char *gpsProcMethodStr =
1154                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1155        if (gpsLongStr == NULL ||
1156                gpsAltitudeStr == NULL ||
1157                gpsTimeStr == NULL ||
1158                gpsProcMethodStr == NULL) {
1159            ALOGE("%s: Incomplete set of GPS parameters provided",
1160                    __FUNCTION__);
1161            return BAD_VALUE;
1162        }
1163        char *endPtr;
1164        errno = 0;
1165        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1166        if (errno || endPtr == gpsLatStr) {
1167            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1168            return BAD_VALUE;
1169        }
1170        errno = 0;
1171        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1172        if (errno || endPtr == gpsLongStr) {
1173            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1174            return BAD_VALUE;
1175        }
1176        errno = 0;
1177        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1178        if (errno || endPtr == gpsAltitudeStr) {
1179            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1180                    gpsAltitudeStr);
1181            return BAD_VALUE;
1182        }
1183        errno = 0;
1184        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1185        if (errno || endPtr == gpsTimeStr) {
1186            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1187            return BAD_VALUE;
1188        }
1189        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1190
1191        validatedParams.gpsEnabled = true;
1192    } else {
1193        validatedParams.gpsEnabled = false;
1194    }
1195
1196    // EFFECT
1197    validatedParams.effectMode = effectModeStringToEnum(
1198        newParams.get(CameraParameters::KEY_EFFECT) );
1199    if (validatedParams.effectMode != effectMode) {
1200        camera_metadata_ro_entry_t availableEffectModes =
1201            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1202        for (i = 0; i < availableEffectModes.count; i++) {
1203            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1204        }
1205        if (i == availableEffectModes.count) {
1206            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1207                    __FUNCTION__,
1208                    newParams.get(CameraParameters::KEY_EFFECT) );
1209            return BAD_VALUE;
1210        }
1211    }
1212
1213    // ANTIBANDING
1214    validatedParams.antibandingMode = abModeStringToEnum(
1215        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1216    if (validatedParams.antibandingMode != antibandingMode) {
1217        camera_metadata_ro_entry_t availableAbModes =
1218            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1219        for (i = 0; i < availableAbModes.count; i++) {
1220            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1221                break;
1222        }
1223        if (i == availableAbModes.count) {
1224            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1225                    __FUNCTION__,
1226                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1227            return BAD_VALUE;
1228        }
1229    }
1230
1231    // SCENE_MODE
1232    validatedParams.sceneMode = sceneModeStringToEnum(
1233        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1234    if (validatedParams.sceneMode != sceneMode &&
1235            validatedParams.sceneMode !=
1236            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1237        camera_metadata_ro_entry_t availableSceneModes =
1238            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1239        for (i = 0; i < availableSceneModes.count; i++) {
1240            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1241                break;
1242        }
1243        if (i == availableSceneModes.count) {
1244            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1245                    __FUNCTION__,
1246                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1247            return BAD_VALUE;
1248        }
1249    }
1250    bool sceneModeSet =
1251            validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1252
1253    // FLASH_MODE
1254    if (sceneModeSet) {
1255        validatedParams.flashMode =
1256                fastInfo.sceneModeOverrides.
1257                        valueFor(validatedParams.sceneMode).flashMode;
1258    } else {
1259        validatedParams.flashMode = FLASH_MODE_INVALID;
1260    }
1261    if (validatedParams.flashMode == FLASH_MODE_INVALID) {
1262        validatedParams.flashMode = flashModeStringToEnum(
1263            newParams.get(CameraParameters::KEY_FLASH_MODE) );
1264    }
1265
1266    if (validatedParams.flashMode != flashMode) {
1267        camera_metadata_ro_entry_t flashAvailable =
1268            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1269        if (!flashAvailable.data.u8[0] &&
1270                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1271            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1272                    "No flash on device", __FUNCTION__,
1273                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1274            return BAD_VALUE;
1275        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1276            camera_metadata_ro_entry_t availableAeModes =
1277                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1278            for (i = 0; i < availableAeModes.count; i++) {
1279                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1280                    break;
1281            }
1282            if (i == availableAeModes.count) {
1283                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1284                        __FUNCTION__,
1285                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1286                return BAD_VALUE;
1287            }
1288        } else if (validatedParams.flashMode == -1) {
1289            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1290                    __FUNCTION__,
1291                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1292            return BAD_VALUE;
1293        }
1294        // Update in case of override
1295        newParams.set(CameraParameters::KEY_FLASH_MODE,
1296                flashModeEnumToString(validatedParams.flashMode));
1297    }
1298
1299    // WHITE_BALANCE
1300    if (sceneModeSet) {
1301        validatedParams.wbMode =
1302                fastInfo.sceneModeOverrides.
1303                        valueFor(validatedParams.sceneMode).wbMode;
1304    } else {
1305        validatedParams.wbMode = ANDROID_CONTROL_AWB_OFF;
1306    }
1307    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_OFF) {
1308        validatedParams.wbMode = wbModeStringToEnum(
1309            newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1310    }
1311    if (validatedParams.wbMode != wbMode) {
1312        camera_metadata_ro_entry_t availableWbModes =
1313            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1314        for (i = 0; i < availableWbModes.count; i++) {
1315            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1316        }
1317        if (i == availableWbModes.count) {
1318            ALOGE("%s: Requested white balance mode %s is not supported",
1319                    __FUNCTION__,
1320                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1321            return BAD_VALUE;
1322        }
1323        // Update in case of override
1324        newParams.set(CameraParameters::KEY_WHITE_BALANCE,
1325                wbModeEnumToString(validatedParams.wbMode));
1326    }
1327
1328    // FOCUS_MODE
1329    if (sceneModeSet) {
1330        validatedParams.focusMode =
1331                fastInfo.sceneModeOverrides.
1332                        valueFor(validatedParams.sceneMode).focusMode;
1333    } else {
1334        validatedParams.focusMode = FOCUS_MODE_INVALID;
1335    }
1336    if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
1337        validatedParams.focusMode = focusModeStringToEnum(
1338                newParams.get(CameraParameters::KEY_FOCUS_MODE) );
1339    }
1340    if (validatedParams.focusMode != focusMode) {
1341        validatedParams.currentAfTriggerId = -1;
1342        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1343            camera_metadata_ro_entry_t minFocusDistance =
1344                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1345            if (minFocusDistance.data.f[0] == 0) {
1346                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1347                        "fixed focus lens",
1348                        __FUNCTION__,
1349                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1350                return BAD_VALUE;
1351            } else if (validatedParams.focusMode !=
1352                    Parameters::FOCUS_MODE_INFINITY) {
1353                camera_metadata_ro_entry_t availableFocusModes =
1354                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1355                for (i = 0; i < availableFocusModes.count; i++) {
1356                    if (validatedParams.focusMode ==
1357                            availableFocusModes.data.u8[i]) break;
1358                }
1359                if (i == availableFocusModes.count) {
1360                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1361                            __FUNCTION__,
1362                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1363                    return BAD_VALUE;
1364                }
1365            }
1366        }
1367        // Always reset shadow focus mode to avoid reverting settings
1368        shadowFocusMode = FOCUS_MODE_INVALID;
1369        // Update in case of override
1370        newParams.set(CameraParameters::KEY_FOCUS_MODE,
1371                focusModeEnumToString(validatedParams.focusMode));
1372    } else {
1373        validatedParams.currentAfTriggerId = currentAfTriggerId;
1374    }
1375
1376    // FOCUS_AREAS
1377    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1378            &validatedParams.focusingAreas);
1379    size_t max3aRegions =
1380        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1381    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1382            max3aRegions);
1383    if (res != OK) {
1384        ALOGE("%s: Requested focus areas are malformed: %s",
1385                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1386        return BAD_VALUE;
1387    }
1388
1389    // EXPOSURE_COMPENSATION
1390    validatedParams.exposureCompensation =
1391        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1392    camera_metadata_ro_entry_t exposureCompensationRange =
1393        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1394    if ((validatedParams.exposureCompensation <
1395            exposureCompensationRange.data.i32[0]) ||
1396        (validatedParams.exposureCompensation >
1397            exposureCompensationRange.data.i32[1])) {
1398        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1399                __FUNCTION__, validatedParams.exposureCompensation);
1400        return BAD_VALUE;
1401    }
1402
1403    // AUTO_EXPOSURE_LOCK (always supported)
1404    validatedParams.autoExposureLock = boolFromString(
1405        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1406
1407    // AUTO_WHITEBALANCE_LOCK (always supported)
1408    validatedParams.autoWhiteBalanceLock = boolFromString(
1409        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1410
1411    // METERING_AREAS
1412    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1413            &validatedParams.meteringAreas);
1414    if (res == OK) {
1415        res = validateAreas(validatedParams.meteringAreas, max3aRegions);
1416    }
1417    if (res != OK) {
1418        ALOGE("%s: Requested metering areas are malformed: %s",
1419                __FUNCTION__,
1420                newParams.get(CameraParameters::KEY_METERING_AREAS));
1421        return BAD_VALUE;
1422    }
1423
1424    // ZOOM
1425    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1426    if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
1427        ALOGE("%s: Requested zoom level %d is not supported",
1428                __FUNCTION__, validatedParams.zoom);
1429        return BAD_VALUE;
1430    }
1431
1432    // VIDEO_SIZE
1433    newParams.getVideoSize(&validatedParams.videoWidth,
1434            &validatedParams.videoHeight);
1435    if (validatedParams.videoWidth != videoWidth ||
1436            validatedParams.videoHeight != videoHeight) {
1437        if (state == RECORD) {
1438            ALOGE("%s: Video size cannot be updated when recording is active!",
1439                    __FUNCTION__);
1440            return BAD_VALUE;
1441        }
1442        camera_metadata_ro_entry_t availableVideoSizes =
1443            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1444        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1445            if ((availableVideoSizes.data.i32[i] ==
1446                    validatedParams.videoWidth) &&
1447                (availableVideoSizes.data.i32[i+1] ==
1448                    validatedParams.videoHeight)) break;
1449        }
1450        if (i == availableVideoSizes.count) {
1451            ALOGE("%s: Requested video size %d x %d is not supported",
1452                    __FUNCTION__, validatedParams.videoWidth,
1453                    validatedParams.videoHeight);
1454            return BAD_VALUE;
1455        }
1456    }
1457
1458    // RECORDING_HINT (always supported)
1459    validatedParams.recordingHint = boolFromString(
1460        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1461
1462    // VIDEO_STABILIZATION
1463    validatedParams.videoStabilization = boolFromString(
1464        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1465    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1466        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1467    if (validatedParams.videoStabilization &&
1468            availableVideoStabilizationModes.count == 1) {
1469        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1470    }
1471
1472    /** Update internal parameters */
1473
1474    *this = validatedParams;
1475
1476    // Need to flatten again in case of overrides
1477    paramsFlattened = newParams.flatten();
1478    params = newParams;
1479
1480    return OK;
1481}
1482
1483status_t Parameters::updateRequest(CameraMetadata *request) const {
1484    ATRACE_CALL();
1485    status_t res;
1486
1487    uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
1488    res = request->update(ANDROID_REQUEST_METADATA_MODE,
1489            &metadataMode, 1);
1490    if (res != OK) return res;
1491
1492    res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1493            previewFpsRange, 2);
1494    if (res != OK) return res;
1495
1496    uint8_t reqWbLock = autoWhiteBalanceLock ?
1497            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1498    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1499            &reqWbLock, 1);
1500
1501    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1502            &effectMode, 1);
1503    if (res != OK) return res;
1504    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1505            &antibandingMode, 1);
1506    if (res != OK) return res;
1507
1508    // android.hardware.Camera requires that when face detect is enabled, the
1509    // camera is in a face-priority mode. HAL2 splits this into separate parts
1510    // (face detection statistics and face priority scene mode). Map from other
1511    // to the other.
1512    bool sceneModeActive =
1513            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1514    uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
1515    if (enableFaceDetect || sceneModeActive) {
1516        reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
1517    }
1518    res = request->update(ANDROID_CONTROL_MODE,
1519            &reqControlMode, 1);
1520    if (res != OK) return res;
1521
1522    uint8_t reqSceneMode =
1523            sceneModeActive ? sceneMode :
1524            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1525            (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1526    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1527            &reqSceneMode, 1);
1528    if (res != OK) return res;
1529
1530    uint8_t reqFlashMode = ANDROID_FLASH_OFF;
1531    uint8_t reqAeMode = ANDROID_CONTROL_AE_OFF;
1532    switch (flashMode) {
1533        case Parameters::FLASH_MODE_OFF:
1534            reqAeMode = ANDROID_CONTROL_AE_ON; break;
1535        case Parameters::FLASH_MODE_AUTO:
1536            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
1537        case Parameters::FLASH_MODE_ON:
1538            reqAeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
1539        case Parameters::FLASH_MODE_TORCH:
1540            reqAeMode = ANDROID_CONTROL_AE_ON;
1541            reqFlashMode = ANDROID_FLASH_TORCH;
1542            break;
1543        case Parameters::FLASH_MODE_RED_EYE:
1544            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
1545        default:
1546            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1547                    cameraId, flashMode);
1548                return BAD_VALUE;
1549    }
1550    res = request->update(ANDROID_FLASH_MODE,
1551            &reqFlashMode, 1);
1552    if (res != OK) return res;
1553    res = request->update(ANDROID_CONTROL_AE_MODE,
1554            &reqAeMode, 1);
1555    if (res != OK) return res;
1556
1557    uint8_t reqAeLock = autoExposureLock ?
1558            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1559    res = request->update(ANDROID_CONTROL_AE_LOCK,
1560            &reqAeLock, 1);
1561    if (res != OK) return res;
1562
1563    res = request->update(ANDROID_CONTROL_AWB_MODE,
1564            &wbMode, 1);
1565    if (res != OK) return res;
1566
1567    float reqFocusDistance = 0; // infinity focus in diopters
1568    uint8_t reqFocusMode = ANDROID_CONTROL_AF_OFF;
1569    switch (focusMode) {
1570        case Parameters::FOCUS_MODE_AUTO:
1571        case Parameters::FOCUS_MODE_MACRO:
1572        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1573        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1574        case Parameters::FOCUS_MODE_EDOF:
1575            reqFocusMode = focusMode;
1576            break;
1577        case Parameters::FOCUS_MODE_INFINITY:
1578        case Parameters::FOCUS_MODE_FIXED:
1579            reqFocusMode = ANDROID_CONTROL_AF_OFF;
1580            break;
1581        default:
1582                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1583                        cameraId, focusMode);
1584                return BAD_VALUE;
1585    }
1586    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1587            &reqFocusDistance, 1);
1588    if (res != OK) return res;
1589    res = request->update(ANDROID_CONTROL_AF_MODE,
1590            &reqFocusMode, 1);
1591    if (res != OK) return res;
1592
1593    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1594    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1595    for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
1596        if (focusingAreas[i].weight != 0) {
1597            reqFocusingAreas[i + 0] =
1598                    normalizedXToArray(focusingAreas[i].left);
1599            reqFocusingAreas[i + 1] =
1600                    normalizedYToArray(focusingAreas[i].top);
1601            reqFocusingAreas[i + 2] =
1602                    normalizedXToArray(focusingAreas[i].right);
1603            reqFocusingAreas[i + 3] =
1604                    normalizedYToArray(focusingAreas[i].bottom);
1605        } else {
1606            reqFocusingAreas[i + 0] = 0;
1607            reqFocusingAreas[i + 1] = 0;
1608            reqFocusingAreas[i + 2] = 0;
1609            reqFocusingAreas[i + 3] = 0;
1610        }
1611        reqFocusingAreas[i + 4] = focusingAreas[i].weight;
1612    }
1613    res = request->update(ANDROID_CONTROL_AF_REGIONS,
1614            reqFocusingAreas, reqFocusingAreasSize);
1615    if (res != OK) return res;
1616    delete[] reqFocusingAreas;
1617
1618    res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
1619            &exposureCompensation, 1);
1620    if (res != OK) return res;
1621
1622    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1623    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1624    for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
1625        if (meteringAreas[i].weight != 0) {
1626            reqMeteringAreas[i + 0] =
1627                normalizedXToArray(meteringAreas[i].left);
1628            reqMeteringAreas[i + 1] =
1629                normalizedYToArray(meteringAreas[i].top);
1630            reqMeteringAreas[i + 2] =
1631                normalizedXToArray(meteringAreas[i].right);
1632            reqMeteringAreas[i + 3] =
1633                normalizedYToArray(meteringAreas[i].bottom);
1634        } else {
1635            reqMeteringAreas[i + 0] = 0;
1636            reqMeteringAreas[i + 1] = 0;
1637            reqMeteringAreas[i + 2] = 0;
1638            reqMeteringAreas[i + 3] = 0;
1639        }
1640        reqMeteringAreas[i + 4] = meteringAreas[i].weight;
1641    }
1642    res = request->update(ANDROID_CONTROL_AE_REGIONS,
1643            reqMeteringAreas, reqMeteringAreasSize);
1644    if (res != OK) return res;
1645
1646    res = request->update(ANDROID_CONTROL_AWB_REGIONS,
1647            reqMeteringAreas, reqMeteringAreasSize);
1648    if (res != OK) return res;
1649    delete[] reqMeteringAreas;
1650
1651    CropRegion crop = calculateCropRegion();
1652    int32_t reqCropRegion[3] = { crop.left, crop.top, crop.width };
1653    res = request->update(ANDROID_SCALER_CROP_REGION,
1654            reqCropRegion, 3);
1655    if (res != OK) return res;
1656
1657    uint8_t reqVstabMode = videoStabilization ?
1658            ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
1659            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
1660    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1661            &reqVstabMode, 1);
1662    if (res != OK) return res;
1663
1664    uint8_t reqFaceDetectMode = enableFaceDetect ?
1665            fastInfo.bestFaceDetectMode :
1666            (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
1667    res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
1668            &reqFaceDetectMode, 1);
1669    if (res != OK) return res;
1670
1671    return OK;
1672}
1673
1674status_t Parameters::updateRequestJpeg(CameraMetadata *request) const {
1675    status_t res;
1676
1677    res = request->update(ANDROID_JPEG_THUMBNAIL_SIZE,
1678            jpegThumbSize, 2);
1679    if (res != OK) return res;
1680    res = request->update(ANDROID_JPEG_THUMBNAIL_QUALITY,
1681            &jpegThumbQuality, 1);
1682    if (res != OK) return res;
1683    res = request->update(ANDROID_JPEG_QUALITY,
1684            &jpegQuality, 1);
1685    if (res != OK) return res;
1686    res = request->update(
1687            ANDROID_JPEG_ORIENTATION,
1688            &jpegRotation, 1);
1689    if (res != OK) return res;
1690
1691    if (gpsEnabled) {
1692        res = request->update(
1693                ANDROID_JPEG_GPS_COORDINATES,
1694                gpsCoordinates, 3);
1695        if (res != OK) return res;
1696        res = request->update(
1697                ANDROID_JPEG_GPS_TIMESTAMP,
1698                &gpsTimestamp, 1);
1699        if (res != OK) return res;
1700        res = request->update(
1701                ANDROID_JPEG_GPS_PROCESSING_METHOD,
1702                gpsProcessingMethod);
1703        if (res != OK) return res;
1704    } else {
1705        res = request->erase(ANDROID_JPEG_GPS_COORDINATES);
1706        if (res != OK) return res;
1707        res = request->erase(ANDROID_JPEG_GPS_TIMESTAMP);
1708        if (res != OK) return res;
1709        res = request->erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
1710        if (res != OK) return res;
1711    }
1712    return OK;
1713}
1714
1715
1716const char* Parameters::getStateName(State state) {
1717#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1718    switch(state) {
1719        CASE_ENUM_TO_CHAR(DISCONNECTED)
1720        CASE_ENUM_TO_CHAR(STOPPED)
1721        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1722        CASE_ENUM_TO_CHAR(PREVIEW)
1723        CASE_ENUM_TO_CHAR(RECORD)
1724        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
1725        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
1726        default:
1727            return "Unknown state!";
1728            break;
1729    }
1730#undef CASE_ENUM_TO_CHAR
1731}
1732
1733int Parameters::formatStringToEnum(const char *format) {
1734    return
1735        !format ?
1736            HAL_PIXEL_FORMAT_YCrCb_420_SP :
1737        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
1738            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
1739        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
1740            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
1741        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
1742            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
1743        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
1744            HAL_PIXEL_FORMAT_YV12 :         // YV12
1745        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
1746            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
1747        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
1748            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
1749        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
1750            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
1751        -1;
1752}
1753
1754const char* Parameters::formatEnumToString(int format) {
1755    const char *fmt;
1756    switch(format) {
1757        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1758            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
1759            break;
1760        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1761            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
1762            break;
1763        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1764            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
1765            break;
1766        case HAL_PIXEL_FORMAT_YV12:        // YV12
1767            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
1768            break;
1769        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
1770            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
1771            break;
1772        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
1773            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
1774            break;
1775        case HAL_PIXEL_FORMAT_RAW_SENSOR:
1776            ALOGW("Raw sensor preview format requested.");
1777            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
1778            break;
1779        default:
1780            ALOGE("%s: Unknown preview format: %x",
1781                    __FUNCTION__,  format);
1782            fmt = NULL;
1783            break;
1784    }
1785    return fmt;
1786}
1787
1788int Parameters::wbModeStringToEnum(const char *wbMode) {
1789    return
1790        !wbMode ?
1791            ANDROID_CONTROL_AWB_AUTO :
1792        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
1793            ANDROID_CONTROL_AWB_AUTO :
1794        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
1795            ANDROID_CONTROL_AWB_INCANDESCENT :
1796        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
1797            ANDROID_CONTROL_AWB_FLUORESCENT :
1798        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
1799            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
1800        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
1801            ANDROID_CONTROL_AWB_DAYLIGHT :
1802        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
1803            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
1804        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
1805            ANDROID_CONTROL_AWB_TWILIGHT :
1806        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
1807            ANDROID_CONTROL_AWB_SHADE :
1808        -1;
1809}
1810
1811const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
1812    switch (wbMode) {
1813        case ANDROID_CONTROL_AWB_AUTO:
1814            return CameraParameters::WHITE_BALANCE_AUTO;
1815        case ANDROID_CONTROL_AWB_INCANDESCENT:
1816            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
1817        case ANDROID_CONTROL_AWB_FLUORESCENT:
1818            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
1819        case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
1820            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
1821        case ANDROID_CONTROL_AWB_DAYLIGHT:
1822            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
1823        case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
1824            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
1825        case ANDROID_CONTROL_AWB_TWILIGHT:
1826            return CameraParameters::WHITE_BALANCE_TWILIGHT;
1827        case ANDROID_CONTROL_AWB_SHADE:
1828            return CameraParameters::WHITE_BALANCE_SHADE;
1829        default:
1830            ALOGE("%s: Unknown AWB mode enum: %d",
1831                    __FUNCTION__, wbMode);
1832            return "unknown";
1833    }
1834}
1835
1836int Parameters::effectModeStringToEnum(const char *effectMode) {
1837    return
1838        !effectMode ?
1839            ANDROID_CONTROL_EFFECT_OFF :
1840        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
1841            ANDROID_CONTROL_EFFECT_OFF :
1842        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
1843            ANDROID_CONTROL_EFFECT_MONO :
1844        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
1845            ANDROID_CONTROL_EFFECT_NEGATIVE :
1846        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
1847            ANDROID_CONTROL_EFFECT_SOLARIZE :
1848        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
1849            ANDROID_CONTROL_EFFECT_SEPIA :
1850        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
1851            ANDROID_CONTROL_EFFECT_POSTERIZE :
1852        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
1853            ANDROID_CONTROL_EFFECT_WHITEBOARD :
1854        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
1855            ANDROID_CONTROL_EFFECT_BLACKBOARD :
1856        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
1857            ANDROID_CONTROL_EFFECT_AQUA :
1858        -1;
1859}
1860
1861int Parameters::abModeStringToEnum(const char *abMode) {
1862    return
1863        !abMode ?
1864            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1865        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
1866            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1867        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
1868            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
1869        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
1870            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
1871        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
1872            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
1873        -1;
1874}
1875
1876int Parameters::sceneModeStringToEnum(const char *sceneMode) {
1877    return
1878        !sceneMode ?
1879            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1880        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
1881            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1882        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
1883            ANDROID_CONTROL_SCENE_MODE_ACTION :
1884        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
1885            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
1886        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
1887            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
1888        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
1889            ANDROID_CONTROL_SCENE_MODE_NIGHT :
1890        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
1891            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
1892        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
1893            ANDROID_CONTROL_SCENE_MODE_THEATRE :
1894        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
1895            ANDROID_CONTROL_SCENE_MODE_BEACH :
1896        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
1897            ANDROID_CONTROL_SCENE_MODE_SNOW :
1898        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
1899            ANDROID_CONTROL_SCENE_MODE_SUNSET :
1900        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
1901            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
1902        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
1903            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
1904        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
1905            ANDROID_CONTROL_SCENE_MODE_SPORTS :
1906        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
1907            ANDROID_CONTROL_SCENE_MODE_PARTY :
1908        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
1909            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
1910        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
1911            ANDROID_CONTROL_SCENE_MODE_BARCODE:
1912        -1;
1913}
1914
1915Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
1916        const char *flashMode) {
1917    return
1918        !flashMode ?
1919            Parameters::FLASH_MODE_INVALID :
1920        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
1921            Parameters::FLASH_MODE_OFF :
1922        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
1923            Parameters::FLASH_MODE_AUTO :
1924        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
1925            Parameters::FLASH_MODE_ON :
1926        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
1927            Parameters::FLASH_MODE_RED_EYE :
1928        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
1929            Parameters::FLASH_MODE_TORCH :
1930        Parameters::FLASH_MODE_INVALID;
1931}
1932
1933const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
1934    switch (flashMode) {
1935        case FLASH_MODE_OFF:
1936            return CameraParameters::FLASH_MODE_OFF;
1937        case FLASH_MODE_AUTO:
1938            return CameraParameters::FLASH_MODE_AUTO;
1939        case FLASH_MODE_ON:
1940            return CameraParameters::FLASH_MODE_ON;
1941        case FLASH_MODE_RED_EYE:
1942            return CameraParameters::FLASH_MODE_RED_EYE;
1943        case FLASH_MODE_TORCH:
1944            return CameraParameters::FLASH_MODE_TORCH;
1945        default:
1946            ALOGE("%s: Unknown flash mode enum %d",
1947                    __FUNCTION__, flashMode);
1948            return "unknown";
1949    }
1950}
1951
1952Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
1953        const char *focusMode) {
1954    return
1955        !focusMode ?
1956            Parameters::FOCUS_MODE_INVALID :
1957        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
1958            Parameters::FOCUS_MODE_AUTO :
1959        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
1960            Parameters::FOCUS_MODE_INFINITY :
1961        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
1962            Parameters::FOCUS_MODE_MACRO :
1963        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
1964            Parameters::FOCUS_MODE_FIXED :
1965        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
1966            Parameters::FOCUS_MODE_EDOF :
1967        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
1968            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
1969        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
1970            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
1971        Parameters::FOCUS_MODE_INVALID;
1972}
1973
1974const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
1975    switch (focusMode) {
1976        case FOCUS_MODE_AUTO:
1977            return CameraParameters::FOCUS_MODE_AUTO;
1978        case FOCUS_MODE_MACRO:
1979            return CameraParameters::FOCUS_MODE_MACRO;
1980        case FOCUS_MODE_CONTINUOUS_VIDEO:
1981            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
1982        case FOCUS_MODE_CONTINUOUS_PICTURE:
1983            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
1984        case FOCUS_MODE_EDOF:
1985            return CameraParameters::FOCUS_MODE_EDOF;
1986        case FOCUS_MODE_INFINITY:
1987            return CameraParameters::FOCUS_MODE_INFINITY;
1988        case FOCUS_MODE_FIXED:
1989            return CameraParameters::FOCUS_MODE_FIXED;
1990        default:
1991            ALOGE("%s: Unknown focus mode enum: %d",
1992                    __FUNCTION__, focusMode);
1993            return "unknown";
1994    }
1995}
1996
1997status_t Parameters::parseAreas(const char *areasCStr,
1998        Vector<Parameters::Area> *areas) {
1999    static const size_t NUM_FIELDS = 5;
2000    areas->clear();
2001    if (areasCStr == NULL) {
2002        // If no key exists, use default (0,0,0,0,0)
2003        areas->push();
2004        return OK;
2005    }
2006    String8 areasStr(areasCStr);
2007    ssize_t areaStart = areasStr.find("(", 0) + 1;
2008    while (areaStart != 0) {
2009        const char* area = areasStr.string() + areaStart;
2010        char *numEnd;
2011        int vals[NUM_FIELDS];
2012        for (size_t i = 0; i < NUM_FIELDS; i++) {
2013            errno = 0;
2014            vals[i] = strtol(area, &numEnd, 10);
2015            if (errno || numEnd == area) return BAD_VALUE;
2016            area = numEnd + 1;
2017        }
2018        areas->push(Parameters::Area(
2019            vals[0], vals[1], vals[2], vals[3], vals[4]) );
2020        areaStart = areasStr.find("(", areaStart) + 1;
2021    }
2022    return OK;
2023}
2024
2025status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
2026                                      size_t maxRegions) {
2027    // Definition of valid area can be found in
2028    // include/camera/CameraParameters.h
2029    if (areas.size() == 0) return BAD_VALUE;
2030    if (areas.size() == 1) {
2031        if (areas[0].left == 0 &&
2032                areas[0].top == 0 &&
2033                areas[0].right == 0 &&
2034                areas[0].bottom == 0 &&
2035                areas[0].weight == 0) {
2036            // Single (0,0,0,0,0) entry is always valid (== driver decides)
2037            return OK;
2038        }
2039    }
2040    if (areas.size() > maxRegions) {
2041        ALOGE("%s: Too many areas requested: %d",
2042                __FUNCTION__, areas.size());
2043        return BAD_VALUE;
2044    }
2045
2046    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2047         a != areas.end(); a++) {
2048        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2049        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2050        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2051        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2052        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2053        if (a->left >= a->right) return BAD_VALUE;
2054        if (a->top >= a->bottom) return BAD_VALUE;
2055    }
2056    return OK;
2057}
2058
2059bool Parameters::boolFromString(const char *boolStr) {
2060    return !boolStr ? false :
2061        !strcmp(boolStr, CameraParameters::TRUE) ? true :
2062        false;
2063}
2064
2065int Parameters::degToTransform(int degrees, bool mirror) {
2066    if (!mirror) {
2067        if (degrees == 0) return 0;
2068        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2069        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2070        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2071    } else {  // Do mirror (horizontal flip)
2072        if (degrees == 0) {           // FLIP_H and ROT_0
2073            return HAL_TRANSFORM_FLIP_H;
2074        } else if (degrees == 90) {   // FLIP_H and ROT_90
2075            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2076        } else if (degrees == 180) {  // FLIP_H and ROT_180
2077            return HAL_TRANSFORM_FLIP_V;
2078        } else if (degrees == 270) {  // FLIP_H and ROT_270
2079            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2080        }
2081    }
2082    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2083    return -1;
2084}
2085
2086int Parameters::arrayXToNormalized(int width) const {
2087    return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2088}
2089
2090int Parameters::arrayYToNormalized(int height) const {
2091    return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2092}
2093
2094int Parameters::normalizedXToArray(int x) const {
2095    return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2096}
2097
2098int Parameters::normalizedYToArray(int y) const {
2099    return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2100}
2101
2102Parameters::CropRegion Parameters::calculateCropRegion(void) const {
2103
2104    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2105
2106    // Need to convert zoom index into a crop rectangle. The rectangle is
2107    // chosen to maximize its area on the sensor
2108
2109    camera_metadata_ro_entry_t maxDigitalZoom =
2110            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2111    // For each zoom step by how many pixels more do we change the zoom
2112    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2113            (NUM_ZOOM_STEPS-1);
2114    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2115    // via interpolating zoom step into a zoom ratio
2116    float zoomRatio = 1 + zoomIncrement * zoom;
2117    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2118        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2119        maxDigitalZoom.data.f[0], zoomRatio);
2120
2121    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2122          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2123          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2124          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2125
2126    /*
2127     * Assumption: On the HAL side each stream buffer calculates its crop
2128     * rectangle as follows:
2129     *   cropRect = (zoomLeft, zoomRight,
2130     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
2131     *
2132     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2133     *      (we can then get into trouble if the cropHeight > arrayHeight).
2134     * By selecting the zoomRatio based on the smallest outputRatio, we
2135     * guarantee this will never happen.
2136     */
2137
2138    // Enumerate all possible output sizes, select the one with the smallest
2139    // aspect ratio
2140    float minOutputWidth, minOutputHeight, minOutputRatio;
2141    {
2142        float outputSizes[][2] = {
2143            { previewWidth,     previewHeight },
2144            { videoWidth,       videoHeight },
2145            /* don't include jpeg thumbnail size - it's valid for
2146               it to be set to (0,0), meaning 'no thumbnail' */
2147        //  { jpegThumbSize[0], jpegThumbSize[1] },
2148            { pictureWidth,     pictureHeight },
2149        };
2150
2151        minOutputWidth = outputSizes[0][0];
2152        minOutputHeight = outputSizes[0][1];
2153        minOutputRatio = minOutputWidth / minOutputHeight;
2154        for (unsigned int i = 0;
2155             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2156             ++i) {
2157
2158            float outputWidth = outputSizes[i][0];
2159            float outputHeight = outputSizes[i][1];
2160            float outputRatio = outputWidth / outputHeight;
2161
2162            if (minOutputRatio > outputRatio) {
2163                minOutputRatio = outputRatio;
2164                minOutputWidth = outputWidth;
2165                minOutputHeight = outputHeight;
2166            }
2167
2168            // and then use this output ratio instead of preview output ratio
2169            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2170                  outputRatio, outputWidth, outputHeight, minOutputRatio);
2171        }
2172    }
2173
2174    /* Ensure that the width/height never go out of bounds
2175     * by scaling across a diffent dimension if an out-of-bounds
2176     * possibility exists.
2177     *
2178     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2179     * calculating the zoomWidth from zoomHeight we'll actually get a
2180     * zoomheight > arrayheight
2181     */
2182    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2183    if (minOutputRatio >= arrayRatio) {
2184        // Adjust the height based on the width
2185        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
2186        zoomHeight = zoomWidth *
2187                minOutputHeight / minOutputWidth;
2188
2189    } else {
2190        // Adjust the width based on the height
2191        zoomHeight = fastInfo.arrayHeight / zoomRatio;
2192        zoomWidth = zoomHeight *
2193                minOutputWidth / minOutputHeight;
2194    }
2195    // centering the zoom area within the active area
2196    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2197    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2198
2199    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2200        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2201
2202
2203    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2204    return crop;
2205}
2206
2207}; // namespace camera2
2208}; // namespace android
2209