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