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