Parameters.cpp revision 260f267288502b73d1920a3701be2038753125b5
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
611    camera_metadata_ro_entry_t max3aRegions =
612        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
613    if (!max3aRegions.count) return NO_INIT;
614
615    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
616            max3aRegions.data.i32[0]);
617    params.set(CameraParameters::KEY_FOCUS_AREAS,
618            "(0,0,0,0,0)");
619    focusingAreas.clear();
620    focusingAreas.add(Parameters::Area(0,0,0,0,0));
621
622    camera_metadata_ro_entry_t availableFocalLengths =
623        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
624    if (!availableFocalLengths.count) return NO_INIT;
625
626    float minFocalLength = availableFocalLengths.data.f[0];
627    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
628
629    camera_metadata_ro_entry_t sensorSize =
630        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
631    if (!sensorSize.count) return NO_INIT;
632
633    // The fields of view here assume infinity focus, maximum wide angle
634    float horizFov = 180 / M_PI *
635            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
636    float vertFov  = 180 / M_PI *
637            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
638    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
639    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
640
641    exposureCompensation = 0;
642    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
643                exposureCompensation);
644
645    camera_metadata_ro_entry_t exposureCompensationRange =
646        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
647    if (!exposureCompensationRange.count) return NO_INIT;
648
649    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
650            exposureCompensationRange.data.i32[1]);
651    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
652            exposureCompensationRange.data.i32[0]);
653
654    camera_metadata_ro_entry_t exposureCompensationStep =
655        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
656    if (!exposureCompensationStep.count) return NO_INIT;
657
658    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
659            (float)exposureCompensationStep.data.r[0].numerator /
660            exposureCompensationStep.data.r[0].denominator);
661
662    autoExposureLock = false;
663    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
664            CameraParameters::FALSE);
665    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
666            CameraParameters::TRUE);
667
668    autoWhiteBalanceLock = false;
669    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
670            CameraParameters::FALSE);
671    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
672            CameraParameters::TRUE);
673
674    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
675    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
676            max3aRegions.data.i32[0]);
677    params.set(CameraParameters::KEY_METERING_AREAS,
678            "(0,0,0,0,0)");
679
680    zoom = 0;
681    params.set(CameraParameters::KEY_ZOOM, zoom);
682    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
683
684    camera_metadata_ro_entry_t maxDigitalZoom =
685        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, /*minCount*/1, /*maxCount*/1);
686    if (!maxDigitalZoom.count) return NO_INIT;
687
688    {
689        String8 zoomRatios;
690        float zoom = 1.f;
691        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
692                (NUM_ZOOM_STEPS-1);
693        bool addComma = false;
694        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
695            if (addComma) zoomRatios += ",";
696            addComma = true;
697            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
698            zoom += zoomIncrement;
699        }
700        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
701    }
702
703    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
704            CameraParameters::TRUE);
705    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
706            CameraParameters::TRUE);
707
708    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
709            "Infinity,Infinity,Infinity");
710
711    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
712            fastInfo.maxFaces);
713    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
714            0);
715
716    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
717            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
718
719    params.set(CameraParameters::KEY_RECORDING_HINT,
720            CameraParameters::FALSE);
721
722    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
723            CameraParameters::TRUE);
724
725    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
726            CameraParameters::FALSE);
727
728    camera_metadata_ro_entry_t availableVideoStabilizationModes =
729        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
730    if (!availableVideoStabilizationModes.count) return NO_INIT;
731
732    if (availableVideoStabilizationModes.count > 1) {
733        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
734                CameraParameters::TRUE);
735    } else {
736        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
737                CameraParameters::FALSE);
738    }
739
740    // Set up initial state for non-Camera.Parameters state variables
741
742    storeMetadataInBuffers = true;
743    playShutterSound = true;
744    enableFaceDetect = false;
745
746    enableFocusMoveMessages = false;
747    afTriggerCounter = 1;
748    currentAfTriggerId = -1;
749
750    precaptureTriggerCounter = 1;
751
752    previewCallbackFlags = 0;
753
754    char value[PROPERTY_VALUE_MAX];
755    property_get("camera.disable_zsl_mode", value, "0");
756    if (!strcmp(value,"1")) {
757        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
758        zslMode = false;
759    } else {
760        zslMode = true;
761    }
762
763    lightFx = LIGHTFX_NONE;
764
765    state = STOPPED;
766
767    paramsFlattened = params.flatten();
768
769    return OK;
770}
771
772String8 Parameters::get() const {
773    return paramsFlattened;
774}
775
776status_t Parameters::buildFastInfo() {
777
778    camera_metadata_ro_entry_t activeArraySize =
779        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
780    if (!activeArraySize.count) return NO_INIT;
781    int32_t arrayWidth = activeArraySize.data.i32[0];
782    int32_t arrayHeight = activeArraySize.data.i32[1];
783
784    camera_metadata_ro_entry_t availableFaceDetectModes =
785        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
786    if (!availableFaceDetectModes.count) return NO_INIT;
787
788    uint8_t bestFaceDetectMode =
789        ANDROID_STATS_FACE_DETECTION_OFF;
790    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
791        switch (availableFaceDetectModes.data.u8[i]) {
792            case ANDROID_STATS_FACE_DETECTION_OFF:
793                break;
794            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
795                if (bestFaceDetectMode !=
796                        ANDROID_STATS_FACE_DETECTION_FULL) {
797                    bestFaceDetectMode =
798                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
799                }
800                break;
801            case ANDROID_STATS_FACE_DETECTION_FULL:
802                bestFaceDetectMode =
803                    ANDROID_STATS_FACE_DETECTION_FULL;
804                break;
805            default:
806                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
807                        __FUNCTION__, cameraId,
808                        availableFaceDetectModes.data.u8[i]);
809                return NO_INIT;
810        }
811    }
812
813    camera_metadata_ro_entry_t maxFacesDetected =
814        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
815    if (!maxFacesDetected.count) return NO_INIT;
816
817    int32_t maxFaces = maxFacesDetected.data.i32[0];
818
819    camera_metadata_ro_entry_t availableSceneModes =
820        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
821    camera_metadata_ro_entry_t sceneModeOverrides =
822        staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES);
823    camera_metadata_ro_entry_t minFocusDistance =
824        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
825    bool fixedLens = (minFocusDistance.data.f[0] == 0);
826
827    if (sceneModeOverrides.count > 0) {
828        // sceneModeOverrides is defined to have 3 entries for each scene mode,
829        // which are AE, AWB, and AF override modes the HAL wants for that scene
830        // mode.
831        const size_t kModesPerSceneMode = 3;
832        if (sceneModeOverrides.count !=
833                availableSceneModes.count * kModesPerSceneMode) {
834            ALOGE("%s: Camera %d: Scene mode override list is an "
835                    "unexpected size: %d (expected %d)", __FUNCTION__,
836                    cameraId, sceneModeOverrides.count,
837                    availableSceneModes.count);
838            return NO_INIT;
839        }
840        for (size_t i = 0; i < availableSceneModes.count; i++) {
841            DeviceInfo::OverrideModes modes;
842            uint8_t aeMode =
843                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
844            switch(aeMode) {
845                case ANDROID_CONTROL_AE_ON:
846                    modes.flashMode = FLASH_MODE_OFF;
847                    break;
848                case ANDROID_CONTROL_AE_ON_AUTO_FLASH:
849                    modes.flashMode = FLASH_MODE_AUTO;
850                    break;
851                case ANDROID_CONTROL_AE_ON_ALWAYS_FLASH:
852                    modes.flashMode = FLASH_MODE_ON;
853                    break;
854                case ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE:
855                    modes.flashMode = FLASH_MODE_RED_EYE;
856                    break;
857                default:
858                    ALOGE("%s: Unknown override AE mode: %d", __FUNCTION__,
859                            aeMode);
860                    modes.flashMode = FLASH_MODE_INVALID;
861                    break;
862            }
863            modes.wbMode =
864                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 1];
865            uint8_t afMode =
866                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
867            switch(afMode) {
868                case ANDROID_CONTROL_AF_OFF:
869                    modes.focusMode = fixedLens ?
870                            FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
871                    break;
872                case ANDROID_CONTROL_AF_AUTO:
873                case ANDROID_CONTROL_AF_MACRO:
874                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
875                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
876                case ANDROID_CONTROL_AF_EDOF:
877                    modes.focusMode = static_cast<focusMode_t>(afMode);
878                    break;
879                default:
880                    ALOGE("%s: Unknown override AF mode: %d", __FUNCTION__,
881                            afMode);
882                    modes.focusMode = FOCUS_MODE_INVALID;
883                    break;
884            }
885            fastInfo.sceneModeOverrides.add(availableSceneModes.data.u8[i],
886                    modes);
887        }
888    }
889
890    fastInfo.arrayWidth = arrayWidth;
891    fastInfo.arrayHeight = arrayHeight;
892    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
893    fastInfo.maxFaces = maxFaces;
894    return OK;
895}
896
897status_t Parameters::buildQuirks() {
898    camera_metadata_ro_entry_t entry;
899    entry = info->find(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO);
900    quirks.triggerAfWithAuto = (entry.count != 0 && entry.data.u8[0] == 1);
901    ALOGV_IF(quirks.triggerAfWithAuto, "Camera %d: Quirk triggerAfWithAuto enabled",
902            cameraId);
903
904    entry = info->find(ANDROID_QUIRKS_USE_ZSL_FORMAT);
905    quirks.useZslFormat = (entry.count != 0 && entry.data.u8[0] == 1);
906    ALOGV_IF(quirks.useZslFormat, "Camera %d: Quirk useZslFormat enabled",
907            cameraId);
908
909    return OK;
910}
911
912camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
913        size_t minCount, size_t maxCount) const {
914    status_t res;
915    camera_metadata_ro_entry_t entry = info->find(tag);
916
917    if (CC_UNLIKELY( entry.count == 0 )) {
918        const char* tagSection = get_camera_metadata_section_name(tag);
919        if (tagSection == NULL) tagSection = "<unknown>";
920        const char* tagName = get_camera_metadata_tag_name(tag);
921        if (tagName == NULL) tagName = "<unknown>";
922
923        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
924                tagSection, tagName, tag);
925    } else if (CC_UNLIKELY(
926            (minCount != 0 && entry.count < minCount) ||
927            (maxCount != 0 && entry.count > maxCount) ) ) {
928        const char* tagSection = get_camera_metadata_section_name(tag);
929        if (tagSection == NULL) tagSection = "<unknown>";
930        const char* tagName = get_camera_metadata_tag_name(tag);
931        if (tagName == NULL) tagName = "<unknown>";
932        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
933                "Expected between %d and %d values, but got %d values",
934                tagSection, tagName, tag, minCount, maxCount, entry.count);
935    }
936
937    return entry;
938}
939
940status_t Parameters::set(const String8& paramString) {
941    status_t res;
942
943    CameraParameters newParams(paramString);
944
945    // TODO: Currently ignoring any changes to supposedly read-only parameters
946    // such as supported preview sizes, etc. Should probably produce an error if
947    // they're changed.
948
949    /** Extract and verify new parameters */
950
951    size_t i;
952
953    Parameters validatedParams(*this);
954
955    // PREVIEW_SIZE
956    newParams.getPreviewSize(&validatedParams.previewWidth,
957            &validatedParams.previewHeight);
958
959    if (validatedParams.previewWidth != previewWidth ||
960            validatedParams.previewHeight != previewHeight) {
961        if (state >= PREVIEW) {
962            ALOGE("%s: Preview size cannot be updated when preview "
963                    "is active! (Currently %d x %d, requested %d x %d",
964                    __FUNCTION__,
965                    previewWidth, previewHeight,
966                    validatedParams.previewWidth, validatedParams.previewHeight);
967            return BAD_VALUE;
968        }
969        camera_metadata_ro_entry_t availablePreviewSizes =
970            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
971        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
972            if ((availablePreviewSizes.data.i32[i] ==
973                    validatedParams.previewWidth) &&
974                (availablePreviewSizes.data.i32[i+1] ==
975                    validatedParams.previewHeight)) break;
976        }
977        if (i == availablePreviewSizes.count) {
978            ALOGE("%s: Requested preview size %d x %d is not supported",
979                    __FUNCTION__, validatedParams.previewWidth,
980                    validatedParams.previewHeight);
981            return BAD_VALUE;
982        }
983    }
984
985    // PREVIEW_FPS_RANGE
986    bool fpsRangeChanged = false;
987    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
988            &validatedParams.previewFpsRange[1]);
989    validatedParams.previewFpsRange[0] /= kFpsToApiScale;
990    validatedParams.previewFpsRange[1] /= kFpsToApiScale;
991
992    if (validatedParams.previewFpsRange[0] != previewFpsRange[0] ||
993            validatedParams.previewFpsRange[1] != previewFpsRange[1]) {
994        fpsRangeChanged = true;
995        camera_metadata_ro_entry_t availablePreviewFpsRanges =
996            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
997        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
998            if ((availablePreviewFpsRanges.data.i32[i] ==
999                    validatedParams.previewFpsRange[0]) &&
1000                (availablePreviewFpsRanges.data.i32[i+1] ==
1001                    validatedParams.previewFpsRange[1]) ) {
1002                break;
1003            }
1004        }
1005        if (i == availablePreviewFpsRanges.count) {
1006            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
1007                __FUNCTION__, validatedParams.previewFpsRange[0],
1008                    validatedParams.previewFpsRange[1]);
1009            return BAD_VALUE;
1010        }
1011        validatedParams.previewFps = validatedParams.previewFpsRange[0];
1012        newParams.setPreviewFrameRate(validatedParams.previewFps);
1013    }
1014
1015    // PREVIEW_FORMAT
1016    validatedParams.previewFormat =
1017            formatStringToEnum(newParams.getPreviewFormat());
1018    if (validatedParams.previewFormat != previewFormat) {
1019        if (state >= PREVIEW) {
1020            ALOGE("%s: Preview format cannot be updated when preview "
1021                    "is active!", __FUNCTION__);
1022            return BAD_VALUE;
1023        }
1024        camera_metadata_ro_entry_t availableFormats =
1025            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1026        for (i = 0; i < availableFormats.count; i++) {
1027            if (availableFormats.data.i32[i] == validatedParams.previewFormat)
1028                break;
1029        }
1030        if (i == availableFormats.count) {
1031            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1032                    __FUNCTION__, newParams.getPreviewFormat(),
1033                    validatedParams.previewFormat);
1034            return BAD_VALUE;
1035        }
1036    }
1037
1038    // PREVIEW_FRAME_RATE
1039    // Deprecated, only use if the preview fps range is unchanged this time.
1040    // The single-value FPS is the same as the minimum of the range.
1041    if (!fpsRangeChanged) {
1042        validatedParams.previewFps = newParams.getPreviewFrameRate();
1043        if (validatedParams.previewFps != previewFps) {
1044            camera_metadata_ro_entry_t availableFrameRates =
1045                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1046            for (i = 0; i < availableFrameRates.count; i+=2) {
1047                if (availableFrameRates.data.i32[i] ==
1048                        validatedParams.previewFps) break;
1049            }
1050            if (i == availableFrameRates.count) {
1051                ALOGE("%s: Requested preview frame rate %d is not supported",
1052                        __FUNCTION__, validatedParams.previewFps);
1053                return BAD_VALUE;
1054            }
1055            validatedParams.previewFpsRange[0] =
1056                    availableFrameRates.data.i32[i];
1057            validatedParams.previewFpsRange[1] =
1058                    availableFrameRates.data.i32[i+1];
1059        }
1060        newParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1061                String8::format("%d,%d",
1062                        validatedParams.previewFpsRange[0] * kFpsToApiScale,
1063                        validatedParams.previewFpsRange[1] * kFpsToApiScale));
1064    }
1065
1066    // PICTURE_SIZE
1067    newParams.getPictureSize(&validatedParams.pictureWidth,
1068            &validatedParams.pictureHeight);
1069    if (validatedParams.pictureWidth == pictureWidth ||
1070            validatedParams.pictureHeight == pictureHeight) {
1071        camera_metadata_ro_entry_t availablePictureSizes =
1072            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1073        for (i = 0; i < availablePictureSizes.count; i+=2) {
1074            if ((availablePictureSizes.data.i32[i] ==
1075                    validatedParams.pictureWidth) &&
1076                (availablePictureSizes.data.i32[i+1] ==
1077                    validatedParams.pictureHeight)) break;
1078        }
1079        if (i == availablePictureSizes.count) {
1080            ALOGE("%s: Requested picture size %d x %d is not supported",
1081                    __FUNCTION__, validatedParams.pictureWidth,
1082                    validatedParams.pictureHeight);
1083            return BAD_VALUE;
1084        }
1085    }
1086
1087    // JPEG_THUMBNAIL_WIDTH/HEIGHT
1088    validatedParams.jpegThumbSize[0] =
1089            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1090    validatedParams.jpegThumbSize[1] =
1091            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1092    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
1093            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
1094        camera_metadata_ro_entry_t availableJpegThumbSizes =
1095            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1096        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1097            if ((availableJpegThumbSizes.data.i32[i] ==
1098                    validatedParams.jpegThumbSize[0]) &&
1099                (availableJpegThumbSizes.data.i32[i+1] ==
1100                    validatedParams.jpegThumbSize[1])) break;
1101        }
1102        if (i == availableJpegThumbSizes.count) {
1103            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1104                    __FUNCTION__, validatedParams.jpegThumbSize[0],
1105                    validatedParams.jpegThumbSize[1]);
1106            return BAD_VALUE;
1107        }
1108    }
1109
1110    // JPEG_THUMBNAIL_QUALITY
1111    validatedParams.jpegThumbQuality =
1112            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1113    if (validatedParams.jpegThumbQuality < 0 ||
1114            validatedParams.jpegThumbQuality > 100) {
1115        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1116                __FUNCTION__, validatedParams.jpegThumbQuality);
1117        return BAD_VALUE;
1118    }
1119
1120    // JPEG_QUALITY
1121    validatedParams.jpegQuality =
1122            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1123    if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
1124        ALOGE("%s: Requested JPEG quality %d is not supported",
1125                __FUNCTION__, validatedParams.jpegQuality);
1126        return BAD_VALUE;
1127    }
1128
1129    // ROTATION
1130    validatedParams.jpegRotation =
1131            newParams.getInt(CameraParameters::KEY_ROTATION);
1132    if (validatedParams.jpegRotation != 0 &&
1133            validatedParams.jpegRotation != 90 &&
1134            validatedParams.jpegRotation != 180 &&
1135            validatedParams.jpegRotation != 270) {
1136        ALOGE("%s: Requested picture rotation angle %d is not supported",
1137                __FUNCTION__, validatedParams.jpegRotation);
1138        return BAD_VALUE;
1139    }
1140
1141    // GPS
1142
1143    const char *gpsLatStr =
1144            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1145    if (gpsLatStr != NULL) {
1146        const char *gpsLongStr =
1147                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1148        const char *gpsAltitudeStr =
1149                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1150        const char *gpsTimeStr =
1151                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1152        const char *gpsProcMethodStr =
1153                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1154        if (gpsLongStr == NULL ||
1155                gpsAltitudeStr == NULL ||
1156                gpsTimeStr == NULL ||
1157                gpsProcMethodStr == NULL) {
1158            ALOGE("%s: Incomplete set of GPS parameters provided",
1159                    __FUNCTION__);
1160            return BAD_VALUE;
1161        }
1162        char *endPtr;
1163        errno = 0;
1164        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1165        if (errno || endPtr == gpsLatStr) {
1166            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1167            return BAD_VALUE;
1168        }
1169        errno = 0;
1170        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1171        if (errno || endPtr == gpsLongStr) {
1172            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1173            return BAD_VALUE;
1174        }
1175        errno = 0;
1176        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1177        if (errno || endPtr == gpsAltitudeStr) {
1178            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1179                    gpsAltitudeStr);
1180            return BAD_VALUE;
1181        }
1182        errno = 0;
1183        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1184        if (errno || endPtr == gpsTimeStr) {
1185            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1186            return BAD_VALUE;
1187        }
1188        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1189
1190        validatedParams.gpsEnabled = true;
1191    } else {
1192        validatedParams.gpsEnabled = false;
1193    }
1194
1195    // EFFECT
1196    validatedParams.effectMode = effectModeStringToEnum(
1197        newParams.get(CameraParameters::KEY_EFFECT) );
1198    if (validatedParams.effectMode != effectMode) {
1199        camera_metadata_ro_entry_t availableEffectModes =
1200            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1201        for (i = 0; i < availableEffectModes.count; i++) {
1202            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1203        }
1204        if (i == availableEffectModes.count) {
1205            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1206                    __FUNCTION__,
1207                    newParams.get(CameraParameters::KEY_EFFECT) );
1208            return BAD_VALUE;
1209        }
1210    }
1211
1212    // ANTIBANDING
1213    validatedParams.antibandingMode = abModeStringToEnum(
1214        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1215    if (validatedParams.antibandingMode != antibandingMode) {
1216        camera_metadata_ro_entry_t availableAbModes =
1217            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1218        for (i = 0; i < availableAbModes.count; i++) {
1219            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1220                break;
1221        }
1222        if (i == availableAbModes.count) {
1223            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1224                    __FUNCTION__,
1225                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1226            return BAD_VALUE;
1227        }
1228    }
1229
1230    // SCENE_MODE
1231    validatedParams.sceneMode = sceneModeStringToEnum(
1232        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1233    if (validatedParams.sceneMode != sceneMode &&
1234            validatedParams.sceneMode !=
1235            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1236        camera_metadata_ro_entry_t availableSceneModes =
1237            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1238        for (i = 0; i < availableSceneModes.count; i++) {
1239            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1240                break;
1241        }
1242        if (i == availableSceneModes.count) {
1243            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1244                    __FUNCTION__,
1245                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1246            return BAD_VALUE;
1247        }
1248    }
1249    bool sceneModeSet =
1250            validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1251
1252    // FLASH_MODE
1253    if (sceneModeSet) {
1254        validatedParams.flashMode =
1255                fastInfo.sceneModeOverrides.
1256                        valueFor(validatedParams.sceneMode).flashMode;
1257    } else {
1258        validatedParams.flashMode = FLASH_MODE_INVALID;
1259    }
1260    if (validatedParams.flashMode == FLASH_MODE_INVALID) {
1261        validatedParams.flashMode = flashModeStringToEnum(
1262            newParams.get(CameraParameters::KEY_FLASH_MODE) );
1263    }
1264
1265    if (validatedParams.flashMode != flashMode) {
1266        camera_metadata_ro_entry_t flashAvailable =
1267            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1268        if (!flashAvailable.data.u8[0] &&
1269                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1270            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1271                    "No flash on device", __FUNCTION__,
1272                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1273            return BAD_VALUE;
1274        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1275            camera_metadata_ro_entry_t availableAeModes =
1276                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1277            for (i = 0; i < availableAeModes.count; i++) {
1278                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1279                    break;
1280            }
1281            if (i == availableAeModes.count) {
1282                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1283                        __FUNCTION__,
1284                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1285                return BAD_VALUE;
1286            }
1287        } else if (validatedParams.flashMode == -1) {
1288            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1289                    __FUNCTION__,
1290                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1291            return BAD_VALUE;
1292        }
1293        // Update in case of override
1294        newParams.set(CameraParameters::KEY_FLASH_MODE,
1295                flashModeEnumToString(validatedParams.flashMode));
1296    }
1297
1298    // WHITE_BALANCE
1299    if (sceneModeSet) {
1300        validatedParams.wbMode =
1301                fastInfo.sceneModeOverrides.
1302                        valueFor(validatedParams.sceneMode).wbMode;
1303    } else {
1304        validatedParams.wbMode = ANDROID_CONTROL_AWB_OFF;
1305    }
1306    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_OFF) {
1307        validatedParams.wbMode = wbModeStringToEnum(
1308            newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1309    }
1310    if (validatedParams.wbMode != wbMode) {
1311        camera_metadata_ro_entry_t availableWbModes =
1312            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1313        for (i = 0; i < availableWbModes.count; i++) {
1314            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1315        }
1316        if (i == availableWbModes.count) {
1317            ALOGE("%s: Requested white balance mode %s is not supported",
1318                    __FUNCTION__,
1319                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1320            return BAD_VALUE;
1321        }
1322        // Update in case of override
1323        newParams.set(CameraParameters::KEY_WHITE_BALANCE,
1324                wbModeEnumToString(validatedParams.wbMode));
1325    }
1326
1327    // FOCUS_MODE
1328    if (sceneModeSet) {
1329        validatedParams.focusMode =
1330                fastInfo.sceneModeOverrides.
1331                        valueFor(validatedParams.sceneMode).focusMode;
1332    } else {
1333        validatedParams.focusMode = FOCUS_MODE_INVALID;
1334    }
1335    if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
1336        validatedParams.focusMode = focusModeStringToEnum(
1337                newParams.get(CameraParameters::KEY_FOCUS_MODE) );
1338    }
1339    if (validatedParams.focusMode != focusMode) {
1340        validatedParams.currentAfTriggerId = -1;
1341        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1342            camera_metadata_ro_entry_t minFocusDistance =
1343                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1344            if (minFocusDistance.data.f[0] == 0) {
1345                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1346                        "fixed focus lens",
1347                        __FUNCTION__,
1348                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1349                return BAD_VALUE;
1350            } else if (validatedParams.focusMode !=
1351                    Parameters::FOCUS_MODE_INFINITY) {
1352                camera_metadata_ro_entry_t availableFocusModes =
1353                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1354                for (i = 0; i < availableFocusModes.count; i++) {
1355                    if (validatedParams.focusMode ==
1356                            availableFocusModes.data.u8[i]) break;
1357                }
1358                if (i == availableFocusModes.count) {
1359                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1360                            __FUNCTION__,
1361                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1362                    return BAD_VALUE;
1363                }
1364            }
1365        }
1366        // Update in case of override
1367        newParams.set(CameraParameters::KEY_FOCUS_MODE,
1368                focusModeEnumToString(validatedParams.focusMode));
1369    } else {
1370        validatedParams.currentAfTriggerId = currentAfTriggerId;
1371    }
1372
1373    // FOCUS_AREAS
1374    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1375            &validatedParams.focusingAreas);
1376    size_t max3aRegions =
1377        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1378    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1379            max3aRegions);
1380    if (res != OK) {
1381        ALOGE("%s: Requested focus areas are malformed: %s",
1382                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1383        return BAD_VALUE;
1384    }
1385
1386    // EXPOSURE_COMPENSATION
1387    validatedParams.exposureCompensation =
1388        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1389    camera_metadata_ro_entry_t exposureCompensationRange =
1390        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1391    if ((validatedParams.exposureCompensation <
1392            exposureCompensationRange.data.i32[0]) ||
1393        (validatedParams.exposureCompensation >
1394            exposureCompensationRange.data.i32[1])) {
1395        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1396                __FUNCTION__, validatedParams.exposureCompensation);
1397        return BAD_VALUE;
1398    }
1399
1400    // AUTO_EXPOSURE_LOCK (always supported)
1401    validatedParams.autoExposureLock = boolFromString(
1402        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1403
1404    // AUTO_WHITEBALANCE_LOCK (always supported)
1405    validatedParams.autoWhiteBalanceLock = boolFromString(
1406        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1407
1408    // METERING_AREAS
1409    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1410            &validatedParams.meteringAreas);
1411    if (res == OK) {
1412        res = validateAreas(validatedParams.meteringAreas, max3aRegions);
1413    }
1414    if (res != OK) {
1415        ALOGE("%s: Requested metering areas are malformed: %s",
1416                __FUNCTION__,
1417                newParams.get(CameraParameters::KEY_METERING_AREAS));
1418        return BAD_VALUE;
1419    }
1420
1421    // ZOOM
1422    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1423    if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
1424        ALOGE("%s: Requested zoom level %d is not supported",
1425                __FUNCTION__, validatedParams.zoom);
1426        return BAD_VALUE;
1427    }
1428
1429    // VIDEO_SIZE
1430    newParams.getVideoSize(&validatedParams.videoWidth,
1431            &validatedParams.videoHeight);
1432    if (validatedParams.videoWidth != videoWidth ||
1433            validatedParams.videoHeight != videoHeight) {
1434        if (state == RECORD) {
1435            ALOGE("%s: Video size cannot be updated when recording is active!",
1436                    __FUNCTION__);
1437            return BAD_VALUE;
1438        }
1439        camera_metadata_ro_entry_t availableVideoSizes =
1440            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1441        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1442            if ((availableVideoSizes.data.i32[i] ==
1443                    validatedParams.videoWidth) &&
1444                (availableVideoSizes.data.i32[i+1] ==
1445                    validatedParams.videoHeight)) break;
1446        }
1447        if (i == availableVideoSizes.count) {
1448            ALOGE("%s: Requested video size %d x %d is not supported",
1449                    __FUNCTION__, validatedParams.videoWidth,
1450                    validatedParams.videoHeight);
1451            return BAD_VALUE;
1452        }
1453    }
1454
1455    // RECORDING_HINT (always supported)
1456    validatedParams.recordingHint = boolFromString(
1457        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1458
1459    // VIDEO_STABILIZATION
1460    validatedParams.videoStabilization = boolFromString(
1461        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1462    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1463        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1464    if (validatedParams.videoStabilization &&
1465            availableVideoStabilizationModes.count == 1) {
1466        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1467    }
1468
1469    /** Update internal parameters */
1470
1471    *this = validatedParams;
1472
1473    // Need to flatten again in case of overrides
1474    paramsFlattened = newParams.flatten();
1475    params = newParams;
1476
1477    return OK;
1478}
1479
1480status_t Parameters::updateRequest(CameraMetadata *request) const {
1481    ATRACE_CALL();
1482    status_t res;
1483
1484    uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
1485    res = request->update(ANDROID_REQUEST_METADATA_MODE,
1486            &metadataMode, 1);
1487    if (res != OK) return res;
1488
1489    res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1490            previewFpsRange, 2);
1491    if (res != OK) return res;
1492
1493    uint8_t reqWbLock = autoWhiteBalanceLock ?
1494            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1495    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1496            &reqWbLock, 1);
1497
1498    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1499            &effectMode, 1);
1500    if (res != OK) return res;
1501    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1502            &antibandingMode, 1);
1503    if (res != OK) return res;
1504
1505    // android.hardware.Camera requires that when face detect is enabled, the
1506    // camera is in a face-priority mode. HAL2 splits this into separate parts
1507    // (face detection statistics and face priority scene mode). Map from other
1508    // to the other.
1509    bool sceneModeActive =
1510            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1511    uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
1512    if (enableFaceDetect || sceneModeActive) {
1513        reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
1514    }
1515    res = request->update(ANDROID_CONTROL_MODE,
1516            &reqControlMode, 1);
1517    if (res != OK) return res;
1518
1519    uint8_t reqSceneMode =
1520            sceneModeActive ? sceneMode :
1521            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1522            (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1523    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1524            &reqSceneMode, 1);
1525    if (res != OK) return res;
1526
1527    uint8_t reqFlashMode = ANDROID_FLASH_OFF;
1528    uint8_t reqAeMode = ANDROID_CONTROL_AE_OFF;
1529    switch (flashMode) {
1530        case Parameters::FLASH_MODE_OFF:
1531            reqAeMode = ANDROID_CONTROL_AE_ON; break;
1532        case Parameters::FLASH_MODE_AUTO:
1533            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
1534        case Parameters::FLASH_MODE_ON:
1535            reqAeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
1536        case Parameters::FLASH_MODE_TORCH:
1537            reqAeMode = ANDROID_CONTROL_AE_ON;
1538            reqFlashMode = ANDROID_FLASH_TORCH;
1539            break;
1540        case Parameters::FLASH_MODE_RED_EYE:
1541            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
1542        default:
1543            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1544                    cameraId, flashMode);
1545                return BAD_VALUE;
1546    }
1547    res = request->update(ANDROID_FLASH_MODE,
1548            &reqFlashMode, 1);
1549    if (res != OK) return res;
1550    res = request->update(ANDROID_CONTROL_AE_MODE,
1551            &reqAeMode, 1);
1552    if (res != OK) return res;
1553
1554    uint8_t reqAeLock = autoExposureLock ?
1555            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1556    res = request->update(ANDROID_CONTROL_AE_LOCK,
1557            &reqAeLock, 1);
1558    if (res != OK) return res;
1559
1560    res = request->update(ANDROID_CONTROL_AWB_MODE,
1561            &wbMode, 1);
1562    if (res != OK) return res;
1563
1564    float reqFocusDistance = 0; // infinity focus in diopters
1565    uint8_t reqFocusMode = ANDROID_CONTROL_AF_OFF;
1566    switch (focusMode) {
1567        case Parameters::FOCUS_MODE_AUTO:
1568        case Parameters::FOCUS_MODE_MACRO:
1569        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1570        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1571        case Parameters::FOCUS_MODE_EDOF:
1572            reqFocusMode = focusMode;
1573            break;
1574        case Parameters::FOCUS_MODE_INFINITY:
1575        case Parameters::FOCUS_MODE_FIXED:
1576            reqFocusMode = ANDROID_CONTROL_AF_OFF;
1577            break;
1578        default:
1579                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1580                        cameraId, focusMode);
1581                return BAD_VALUE;
1582    }
1583    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1584            &reqFocusDistance, 1);
1585    if (res != OK) return res;
1586    res = request->update(ANDROID_CONTROL_AF_MODE,
1587            &reqFocusMode, 1);
1588    if (res != OK) return res;
1589
1590    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1591    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1592    for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
1593        if (focusingAreas[i].weight != 0) {
1594            reqFocusingAreas[i + 0] =
1595                    normalizedXToArray(focusingAreas[i].left);
1596            reqFocusingAreas[i + 1] =
1597                    normalizedYToArray(focusingAreas[i].top);
1598            reqFocusingAreas[i + 2] =
1599                    normalizedXToArray(focusingAreas[i].right);
1600            reqFocusingAreas[i + 3] =
1601                    normalizedYToArray(focusingAreas[i].bottom);
1602        } else {
1603            reqFocusingAreas[i + 0] = 0;
1604            reqFocusingAreas[i + 1] = 0;
1605            reqFocusingAreas[i + 2] = 0;
1606            reqFocusingAreas[i + 3] = 0;
1607        }
1608        reqFocusingAreas[i + 4] = focusingAreas[i].weight;
1609    }
1610    res = request->update(ANDROID_CONTROL_AF_REGIONS,
1611            reqFocusingAreas, reqFocusingAreasSize);
1612    if (res != OK) return res;
1613    delete[] reqFocusingAreas;
1614
1615    res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
1616            &exposureCompensation, 1);
1617    if (res != OK) return res;
1618
1619    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1620    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1621    for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
1622        if (meteringAreas[i].weight != 0) {
1623            reqMeteringAreas[i + 0] =
1624                normalizedXToArray(meteringAreas[i].left);
1625            reqMeteringAreas[i + 1] =
1626                normalizedYToArray(meteringAreas[i].top);
1627            reqMeteringAreas[i + 2] =
1628                normalizedXToArray(meteringAreas[i].right);
1629            reqMeteringAreas[i + 3] =
1630                normalizedYToArray(meteringAreas[i].bottom);
1631        } else {
1632            reqMeteringAreas[i + 0] = 0;
1633            reqMeteringAreas[i + 1] = 0;
1634            reqMeteringAreas[i + 2] = 0;
1635            reqMeteringAreas[i + 3] = 0;
1636        }
1637        reqMeteringAreas[i + 4] = meteringAreas[i].weight;
1638    }
1639    res = request->update(ANDROID_CONTROL_AE_REGIONS,
1640            reqMeteringAreas, reqMeteringAreasSize);
1641    if (res != OK) return res;
1642
1643    res = request->update(ANDROID_CONTROL_AWB_REGIONS,
1644            reqMeteringAreas, reqMeteringAreasSize);
1645    if (res != OK) return res;
1646    delete[] reqMeteringAreas;
1647
1648    CropRegion crop = calculateCropRegion();
1649    int32_t reqCropRegion[3] = { crop.left, crop.top, crop.width };
1650    res = request->update(ANDROID_SCALER_CROP_REGION,
1651            reqCropRegion, 3);
1652    if (res != OK) return res;
1653
1654    uint8_t reqVstabMode = videoStabilization ?
1655            ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
1656            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
1657    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1658            &reqVstabMode, 1);
1659    if (res != OK) return res;
1660
1661    uint8_t reqFaceDetectMode = enableFaceDetect ?
1662            fastInfo.bestFaceDetectMode :
1663            (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
1664    res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
1665            &reqFaceDetectMode, 1);
1666    if (res != OK) return res;
1667
1668    return OK;
1669}
1670
1671const char* Parameters::getStateName(State state) {
1672#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1673    switch(state) {
1674        CASE_ENUM_TO_CHAR(DISCONNECTED)
1675        CASE_ENUM_TO_CHAR(STOPPED)
1676        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1677        CASE_ENUM_TO_CHAR(PREVIEW)
1678        CASE_ENUM_TO_CHAR(RECORD)
1679        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
1680        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
1681        default:
1682            return "Unknown state!";
1683            break;
1684    }
1685#undef CASE_ENUM_TO_CHAR
1686}
1687
1688int Parameters::formatStringToEnum(const char *format) {
1689    return
1690        !format ?
1691            HAL_PIXEL_FORMAT_YCrCb_420_SP :
1692        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
1693            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
1694        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
1695            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
1696        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
1697            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
1698        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
1699            HAL_PIXEL_FORMAT_YV12 :         // YV12
1700        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
1701            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
1702        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
1703            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
1704        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
1705            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
1706        -1;
1707}
1708
1709const char* Parameters::formatEnumToString(int format) {
1710    const char *fmt;
1711    switch(format) {
1712        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1713            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
1714            break;
1715        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1716            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
1717            break;
1718        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1719            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
1720            break;
1721        case HAL_PIXEL_FORMAT_YV12:        // YV12
1722            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
1723            break;
1724        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
1725            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
1726            break;
1727        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
1728            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
1729            break;
1730        case HAL_PIXEL_FORMAT_RAW_SENSOR:
1731            ALOGW("Raw sensor preview format requested.");
1732            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
1733            break;
1734        default:
1735            ALOGE("%s: Unknown preview format: %x",
1736                    __FUNCTION__,  format);
1737            fmt = NULL;
1738            break;
1739    }
1740    return fmt;
1741}
1742
1743int Parameters::wbModeStringToEnum(const char *wbMode) {
1744    return
1745        !wbMode ?
1746            ANDROID_CONTROL_AWB_AUTO :
1747        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
1748            ANDROID_CONTROL_AWB_AUTO :
1749        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
1750            ANDROID_CONTROL_AWB_INCANDESCENT :
1751        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
1752            ANDROID_CONTROL_AWB_FLUORESCENT :
1753        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
1754            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
1755        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
1756            ANDROID_CONTROL_AWB_DAYLIGHT :
1757        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
1758            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
1759        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
1760            ANDROID_CONTROL_AWB_TWILIGHT :
1761        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
1762            ANDROID_CONTROL_AWB_SHADE :
1763        -1;
1764}
1765
1766const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
1767    switch (wbMode) {
1768        case ANDROID_CONTROL_AWB_AUTO:
1769            return CameraParameters::WHITE_BALANCE_AUTO;
1770        case ANDROID_CONTROL_AWB_INCANDESCENT:
1771            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
1772        case ANDROID_CONTROL_AWB_FLUORESCENT:
1773            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
1774        case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
1775            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
1776        case ANDROID_CONTROL_AWB_DAYLIGHT:
1777            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
1778        case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
1779            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
1780        case ANDROID_CONTROL_AWB_TWILIGHT:
1781            return CameraParameters::WHITE_BALANCE_TWILIGHT;
1782        case ANDROID_CONTROL_AWB_SHADE:
1783            return CameraParameters::WHITE_BALANCE_SHADE;
1784        default:
1785            ALOGE("%s: Unknown AWB mode enum: %d",
1786                    __FUNCTION__, wbMode);
1787            return "unknown";
1788    }
1789}
1790
1791int Parameters::effectModeStringToEnum(const char *effectMode) {
1792    return
1793        !effectMode ?
1794            ANDROID_CONTROL_EFFECT_OFF :
1795        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
1796            ANDROID_CONTROL_EFFECT_OFF :
1797        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
1798            ANDROID_CONTROL_EFFECT_MONO :
1799        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
1800            ANDROID_CONTROL_EFFECT_NEGATIVE :
1801        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
1802            ANDROID_CONTROL_EFFECT_SOLARIZE :
1803        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
1804            ANDROID_CONTROL_EFFECT_SEPIA :
1805        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
1806            ANDROID_CONTROL_EFFECT_POSTERIZE :
1807        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
1808            ANDROID_CONTROL_EFFECT_WHITEBOARD :
1809        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
1810            ANDROID_CONTROL_EFFECT_BLACKBOARD :
1811        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
1812            ANDROID_CONTROL_EFFECT_AQUA :
1813        -1;
1814}
1815
1816int Parameters::abModeStringToEnum(const char *abMode) {
1817    return
1818        !abMode ?
1819            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1820        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
1821            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1822        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
1823            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
1824        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
1825            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
1826        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
1827            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
1828        -1;
1829}
1830
1831int Parameters::sceneModeStringToEnum(const char *sceneMode) {
1832    return
1833        !sceneMode ?
1834            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1835        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
1836            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1837        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
1838            ANDROID_CONTROL_SCENE_MODE_ACTION :
1839        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
1840            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
1841        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
1842            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
1843        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
1844            ANDROID_CONTROL_SCENE_MODE_NIGHT :
1845        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
1846            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
1847        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
1848            ANDROID_CONTROL_SCENE_MODE_THEATRE :
1849        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
1850            ANDROID_CONTROL_SCENE_MODE_BEACH :
1851        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
1852            ANDROID_CONTROL_SCENE_MODE_SNOW :
1853        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
1854            ANDROID_CONTROL_SCENE_MODE_SUNSET :
1855        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
1856            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
1857        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
1858            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
1859        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
1860            ANDROID_CONTROL_SCENE_MODE_SPORTS :
1861        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
1862            ANDROID_CONTROL_SCENE_MODE_PARTY :
1863        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
1864            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
1865        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
1866            ANDROID_CONTROL_SCENE_MODE_BARCODE:
1867        -1;
1868}
1869
1870Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
1871        const char *flashMode) {
1872    return
1873        !flashMode ?
1874            Parameters::FLASH_MODE_INVALID :
1875        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
1876            Parameters::FLASH_MODE_OFF :
1877        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
1878            Parameters::FLASH_MODE_AUTO :
1879        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
1880            Parameters::FLASH_MODE_ON :
1881        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
1882            Parameters::FLASH_MODE_RED_EYE :
1883        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
1884            Parameters::FLASH_MODE_TORCH :
1885        Parameters::FLASH_MODE_INVALID;
1886}
1887
1888const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
1889    switch (flashMode) {
1890        case FLASH_MODE_OFF:
1891            return CameraParameters::FLASH_MODE_OFF;
1892        case FLASH_MODE_AUTO:
1893            return CameraParameters::FLASH_MODE_AUTO;
1894        case FLASH_MODE_ON:
1895            return CameraParameters::FLASH_MODE_ON;
1896        case FLASH_MODE_RED_EYE:
1897            return CameraParameters::FLASH_MODE_RED_EYE;
1898        case FLASH_MODE_TORCH:
1899            return CameraParameters::FLASH_MODE_TORCH;
1900        default:
1901            ALOGE("%s: Unknown flash mode enum %d",
1902                    __FUNCTION__, flashMode);
1903            return "unknown";
1904    }
1905}
1906
1907Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
1908        const char *focusMode) {
1909    return
1910        !focusMode ?
1911            Parameters::FOCUS_MODE_INVALID :
1912        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
1913            Parameters::FOCUS_MODE_AUTO :
1914        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
1915            Parameters::FOCUS_MODE_INFINITY :
1916        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
1917            Parameters::FOCUS_MODE_MACRO :
1918        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
1919            Parameters::FOCUS_MODE_FIXED :
1920        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
1921            Parameters::FOCUS_MODE_EDOF :
1922        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
1923            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
1924        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
1925            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
1926        Parameters::FOCUS_MODE_INVALID;
1927}
1928
1929const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
1930    switch (focusMode) {
1931        case FOCUS_MODE_AUTO:
1932            return CameraParameters::FOCUS_MODE_AUTO;
1933        case FOCUS_MODE_MACRO:
1934            return CameraParameters::FOCUS_MODE_MACRO;
1935        case FOCUS_MODE_CONTINUOUS_VIDEO:
1936            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
1937        case FOCUS_MODE_CONTINUOUS_PICTURE:
1938            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
1939        case FOCUS_MODE_EDOF:
1940            return CameraParameters::FOCUS_MODE_EDOF;
1941        case FOCUS_MODE_INFINITY:
1942            return CameraParameters::FOCUS_MODE_INFINITY;
1943        case FOCUS_MODE_FIXED:
1944            return CameraParameters::FOCUS_MODE_FIXED;
1945        default:
1946            ALOGE("%s: Unknown focus mode enum: %d",
1947                    __FUNCTION__, focusMode);
1948            return "unknown";
1949    }
1950}
1951
1952status_t Parameters::parseAreas(const char *areasCStr,
1953        Vector<Parameters::Area> *areas) {
1954    static const size_t NUM_FIELDS = 5;
1955    areas->clear();
1956    if (areasCStr == NULL) {
1957        // If no key exists, use default (0,0,0,0,0)
1958        areas->push();
1959        return OK;
1960    }
1961    String8 areasStr(areasCStr);
1962    ssize_t areaStart = areasStr.find("(", 0) + 1;
1963    while (areaStart != 0) {
1964        const char* area = areasStr.string() + areaStart;
1965        char *numEnd;
1966        int vals[NUM_FIELDS];
1967        for (size_t i = 0; i < NUM_FIELDS; i++) {
1968            errno = 0;
1969            vals[i] = strtol(area, &numEnd, 10);
1970            if (errno || numEnd == area) return BAD_VALUE;
1971            area = numEnd + 1;
1972        }
1973        areas->push(Parameters::Area(
1974            vals[0], vals[1], vals[2], vals[3], vals[4]) );
1975        areaStart = areasStr.find("(", areaStart) + 1;
1976    }
1977    return OK;
1978}
1979
1980status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
1981                                      size_t maxRegions) {
1982    // Definition of valid area can be found in
1983    // include/camera/CameraParameters.h
1984    if (areas.size() == 0) return BAD_VALUE;
1985    if (areas.size() == 1) {
1986        if (areas[0].left == 0 &&
1987                areas[0].top == 0 &&
1988                areas[0].right == 0 &&
1989                areas[0].bottom == 0 &&
1990                areas[0].weight == 0) {
1991            // Single (0,0,0,0,0) entry is always valid (== driver decides)
1992            return OK;
1993        }
1994    }
1995    if (areas.size() > maxRegions) {
1996        ALOGE("%s: Too many areas requested: %d",
1997                __FUNCTION__, areas.size());
1998        return BAD_VALUE;
1999    }
2000
2001    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2002         a != areas.end(); a++) {
2003        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2004        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2005        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2006        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2007        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2008        if (a->left >= a->right) return BAD_VALUE;
2009        if (a->top >= a->bottom) return BAD_VALUE;
2010    }
2011    return OK;
2012}
2013
2014bool Parameters::boolFromString(const char *boolStr) {
2015    return !boolStr ? false :
2016        !strcmp(boolStr, CameraParameters::TRUE) ? true :
2017        false;
2018}
2019
2020int Parameters::degToTransform(int degrees, bool mirror) {
2021    if (!mirror) {
2022        if (degrees == 0) return 0;
2023        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2024        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2025        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2026    } else {  // Do mirror (horizontal flip)
2027        if (degrees == 0) {           // FLIP_H and ROT_0
2028            return HAL_TRANSFORM_FLIP_H;
2029        } else if (degrees == 90) {   // FLIP_H and ROT_90
2030            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2031        } else if (degrees == 180) {  // FLIP_H and ROT_180
2032            return HAL_TRANSFORM_FLIP_V;
2033        } else if (degrees == 270) {  // FLIP_H and ROT_270
2034            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2035        }
2036    }
2037    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2038    return -1;
2039}
2040
2041int Parameters::arrayXToNormalized(int width) const {
2042    return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2043}
2044
2045int Parameters::arrayYToNormalized(int height) const {
2046    return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2047}
2048
2049int Parameters::normalizedXToArray(int x) const {
2050    return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2051}
2052
2053int Parameters::normalizedYToArray(int y) const {
2054    return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2055}
2056
2057Parameters::CropRegion Parameters::calculateCropRegion(void) const {
2058
2059    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2060
2061    // Need to convert zoom index into a crop rectangle. The rectangle is
2062    // chosen to maximize its area on the sensor
2063
2064    camera_metadata_ro_entry_t maxDigitalZoom =
2065            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2066    // For each zoom step by how many pixels more do we change the zoom
2067    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2068            (NUM_ZOOM_STEPS-1);
2069    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2070    // via interpolating zoom step into a zoom ratio
2071    float zoomRatio = 1 + zoomIncrement * zoom;
2072    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2073        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2074        maxDigitalZoom.data.f[0], zoomRatio);
2075
2076    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2077          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2078          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2079          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2080
2081    /*
2082     * Assumption: On the HAL side each stream buffer calculates its crop
2083     * rectangle as follows:
2084     *   cropRect = (zoomLeft, zoomRight,
2085     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
2086     *
2087     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2088     *      (we can then get into trouble if the cropHeight > arrayHeight).
2089     * By selecting the zoomRatio based on the smallest outputRatio, we
2090     * guarantee this will never happen.
2091     */
2092
2093    // Enumerate all possible output sizes, select the one with the smallest
2094    // aspect ratio
2095    float minOutputWidth, minOutputHeight, minOutputRatio;
2096    {
2097        float outputSizes[][2] = {
2098            { previewWidth,     previewHeight },
2099            { videoWidth,       videoHeight },
2100            /* don't include jpeg thumbnail size - it's valid for
2101               it to be set to (0,0), meaning 'no thumbnail' */
2102        //  { jpegThumbSize[0], jpegThumbSize[1] },
2103            { pictureWidth,     pictureHeight },
2104        };
2105
2106        minOutputWidth = outputSizes[0][0];
2107        minOutputHeight = outputSizes[0][1];
2108        minOutputRatio = minOutputWidth / minOutputHeight;
2109        for (unsigned int i = 0;
2110             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2111             ++i) {
2112
2113            float outputWidth = outputSizes[i][0];
2114            float outputHeight = outputSizes[i][1];
2115            float outputRatio = outputWidth / outputHeight;
2116
2117            if (minOutputRatio > outputRatio) {
2118                minOutputRatio = outputRatio;
2119                minOutputWidth = outputWidth;
2120                minOutputHeight = outputHeight;
2121            }
2122
2123            // and then use this output ratio instead of preview output ratio
2124            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2125                  outputRatio, outputWidth, outputHeight, minOutputRatio);
2126        }
2127    }
2128
2129    /* Ensure that the width/height never go out of bounds
2130     * by scaling across a diffent dimension if an out-of-bounds
2131     * possibility exists.
2132     *
2133     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2134     * calculating the zoomWidth from zoomHeight we'll actually get a
2135     * zoomheight > arrayheight
2136     */
2137    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2138    if (minOutputRatio >= arrayRatio) {
2139        // Adjust the height based on the width
2140        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
2141        zoomHeight = zoomWidth *
2142                minOutputHeight / minOutputWidth;
2143
2144    } else {
2145        // Adjust the width based on the height
2146        zoomHeight = fastInfo.arrayHeight / zoomRatio;
2147        zoomWidth = zoomHeight *
2148                minOutputWidth / minOutputHeight;
2149    }
2150    // centering the zoom area within the active area
2151    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2152    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2153
2154    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2155        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2156
2157
2158    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2159    return crop;
2160}
2161
2162}; // namespace camera2
2163}; // namespace android
2164