Parameters.cpp revision c90f4c7c5838e4dee2f550c4d581e7205e666faa
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_UNSUPPORTED;
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_UNSUPPORTED:
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: %zu (expected %zu)", __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 %zu and %zu values, but got %zu 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_UNSUPPORTED) {
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_UNSUPPORTED;
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
1754    if (intent.count == 0) return BAD_VALUE;
1755
1756    if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
1757        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1758                fastInfo.bestStillCaptureFpsRange, 2);
1759    } else {
1760        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1761                previewFpsRange, 2);
1762    }
1763    if (res != OK) return res;
1764
1765    uint8_t reqWbLock = autoWhiteBalanceLock ?
1766            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1767    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1768            &reqWbLock, 1);
1769
1770    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1771            &effectMode, 1);
1772    if (res != OK) return res;
1773    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1774            &antibandingMode, 1);
1775    if (res != OK) return res;
1776
1777    // android.hardware.Camera requires that when face detect is enabled, the
1778    // camera is in a face-priority mode. HAL2 splits this into separate parts
1779    // (face detection statistics and face priority scene mode). Map from other
1780    // to the other.
1781    bool sceneModeActive =
1782            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1783    uint8_t reqControlMode = ANDROID_CONTROL_MODE_AUTO;
1784    if (enableFaceDetect || sceneModeActive) {
1785        reqControlMode = ANDROID_CONTROL_MODE_USE_SCENE_MODE;
1786    }
1787    res = request->update(ANDROID_CONTROL_MODE,
1788            &reqControlMode, 1);
1789    if (res != OK) return res;
1790
1791    uint8_t reqSceneMode =
1792            sceneModeActive ? sceneMode :
1793            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1794            (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1795    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1796            &reqSceneMode, 1);
1797    if (res != OK) return res;
1798
1799    uint8_t reqFlashMode = ANDROID_FLASH_MODE_OFF;
1800    uint8_t reqAeMode = ANDROID_CONTROL_AE_MODE_OFF;
1801    switch (flashMode) {
1802        case Parameters::FLASH_MODE_OFF:
1803            reqAeMode = ANDROID_CONTROL_AE_MODE_ON; break;
1804        case Parameters::FLASH_MODE_AUTO:
1805            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; break;
1806        case Parameters::FLASH_MODE_ON:
1807            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH; break;
1808        case Parameters::FLASH_MODE_TORCH:
1809            reqAeMode = ANDROID_CONTROL_AE_MODE_ON;
1810            reqFlashMode = ANDROID_FLASH_MODE_TORCH;
1811            break;
1812        case Parameters::FLASH_MODE_RED_EYE:
1813            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; break;
1814        default:
1815            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1816                    cameraId, flashMode);
1817                return BAD_VALUE;
1818    }
1819    res = request->update(ANDROID_FLASH_MODE,
1820            &reqFlashMode, 1);
1821    if (res != OK) return res;
1822    res = request->update(ANDROID_CONTROL_AE_MODE,
1823            &reqAeMode, 1);
1824    if (res != OK) return res;
1825
1826    uint8_t reqAeLock = autoExposureLock ?
1827            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1828    res = request->update(ANDROID_CONTROL_AE_LOCK,
1829            &reqAeLock, 1);
1830    if (res != OK) return res;
1831
1832    res = request->update(ANDROID_CONTROL_AWB_MODE,
1833            &wbMode, 1);
1834    if (res != OK) return res;
1835
1836    float reqFocusDistance = 0; // infinity focus in diopters
1837    uint8_t reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1838    switch (focusMode) {
1839        case Parameters::FOCUS_MODE_AUTO:
1840        case Parameters::FOCUS_MODE_MACRO:
1841        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1842        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1843        case Parameters::FOCUS_MODE_EDOF:
1844            reqFocusMode = focusMode;
1845            break;
1846        case Parameters::FOCUS_MODE_INFINITY:
1847        case Parameters::FOCUS_MODE_FIXED:
1848            reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1849            break;
1850        default:
1851                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1852                        cameraId, focusMode);
1853                return BAD_VALUE;
1854    }
1855    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1856            &reqFocusDistance, 1);
1857    if (res != OK) return res;
1858    res = request->update(ANDROID_CONTROL_AF_MODE,
1859            &reqFocusMode, 1);
1860    if (res != OK) return res;
1861
1862    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1863    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1864    for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
1865        if (focusingAreas[i].weight != 0) {
1866            reqFocusingAreas[i + 0] =
1867                    normalizedXToArray(focusingAreas[i].left);
1868            reqFocusingAreas[i + 1] =
1869                    normalizedYToArray(focusingAreas[i].top);
1870            reqFocusingAreas[i + 2] =
1871                    normalizedXToArray(focusingAreas[i].right);
1872            reqFocusingAreas[i + 3] =
1873                    normalizedYToArray(focusingAreas[i].bottom);
1874        } else {
1875            reqFocusingAreas[i + 0] = 0;
1876            reqFocusingAreas[i + 1] = 0;
1877            reqFocusingAreas[i + 2] = 0;
1878            reqFocusingAreas[i + 3] = 0;
1879        }
1880        reqFocusingAreas[i + 4] = focusingAreas[i].weight;
1881    }
1882    res = request->update(ANDROID_CONTROL_AF_REGIONS,
1883            reqFocusingAreas, reqFocusingAreasSize);
1884    if (res != OK) return res;
1885    delete[] reqFocusingAreas;
1886
1887    res = request->update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1888            &exposureCompensation, 1);
1889    if (res != OK) return res;
1890
1891    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1892    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1893    for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
1894        if (meteringAreas[i].weight != 0) {
1895            reqMeteringAreas[i + 0] =
1896                normalizedXToArray(meteringAreas[i].left);
1897            reqMeteringAreas[i + 1] =
1898                normalizedYToArray(meteringAreas[i].top);
1899            reqMeteringAreas[i + 2] =
1900                normalizedXToArray(meteringAreas[i].right);
1901            reqMeteringAreas[i + 3] =
1902                normalizedYToArray(meteringAreas[i].bottom);
1903        } else {
1904            reqMeteringAreas[i + 0] = 0;
1905            reqMeteringAreas[i + 1] = 0;
1906            reqMeteringAreas[i + 2] = 0;
1907            reqMeteringAreas[i + 3] = 0;
1908        }
1909        reqMeteringAreas[i + 4] = meteringAreas[i].weight;
1910    }
1911    res = request->update(ANDROID_CONTROL_AE_REGIONS,
1912            reqMeteringAreas, reqMeteringAreasSize);
1913    if (res != OK) return res;
1914
1915    delete[] reqMeteringAreas;
1916
1917    /* don't include jpeg thumbnail size - it's valid for
1918       it to be set to (0,0), meaning 'no thumbnail' */
1919    CropRegion crop = calculateCropRegion( (CropRegion::Outputs)(
1920            CropRegion::OUTPUT_PREVIEW     |
1921            CropRegion::OUTPUT_VIDEO       |
1922            CropRegion::OUTPUT_PICTURE    ));
1923    int32_t reqCropRegion[4] = {
1924        static_cast<int32_t>(crop.left),
1925        static_cast<int32_t>(crop.top),
1926        static_cast<int32_t>(crop.width),
1927        static_cast<int32_t>(crop.height)
1928    };
1929    res = request->update(ANDROID_SCALER_CROP_REGION,
1930            reqCropRegion, 4);
1931    if (res != OK) return res;
1932
1933    uint8_t reqVstabMode = videoStabilization ?
1934            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON :
1935            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
1936    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1937            &reqVstabMode, 1);
1938    if (res != OK) return res;
1939
1940    uint8_t reqFaceDetectMode = enableFaceDetect ?
1941            fastInfo.bestFaceDetectMode :
1942            (uint8_t)ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
1943    res = request->update(ANDROID_STATISTICS_FACE_DETECT_MODE,
1944            &reqFaceDetectMode, 1);
1945    if (res != OK) return res;
1946
1947    return OK;
1948}
1949
1950status_t Parameters::updateRequestJpeg(CameraMetadata *request) const {
1951    status_t res;
1952
1953    res = request->update(ANDROID_JPEG_THUMBNAIL_SIZE,
1954            jpegThumbSize, 2);
1955    if (res != OK) return res;
1956    res = request->update(ANDROID_JPEG_THUMBNAIL_QUALITY,
1957            &jpegThumbQuality, 1);
1958    if (res != OK) return res;
1959    res = request->update(ANDROID_JPEG_QUALITY,
1960            &jpegQuality, 1);
1961    if (res != OK) return res;
1962    res = request->update(
1963            ANDROID_JPEG_ORIENTATION,
1964            &jpegRotation, 1);
1965    if (res != OK) return res;
1966
1967    if (gpsEnabled) {
1968        res = request->update(
1969                ANDROID_JPEG_GPS_COORDINATES,
1970                gpsCoordinates, 3);
1971        if (res != OK) return res;
1972        res = request->update(
1973                ANDROID_JPEG_GPS_TIMESTAMP,
1974                &gpsTimestamp, 1);
1975        if (res != OK) return res;
1976        res = request->update(
1977                ANDROID_JPEG_GPS_PROCESSING_METHOD,
1978                gpsProcessingMethod);
1979        if (res != OK) return res;
1980    } else {
1981        res = request->erase(ANDROID_JPEG_GPS_COORDINATES);
1982        if (res != OK) return res;
1983        res = request->erase(ANDROID_JPEG_GPS_TIMESTAMP);
1984        if (res != OK) return res;
1985        res = request->erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
1986        if (res != OK) return res;
1987    }
1988    return OK;
1989}
1990
1991
1992const char* Parameters::getStateName(State state) {
1993#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1994    switch(state) {
1995        CASE_ENUM_TO_CHAR(DISCONNECTED)
1996        CASE_ENUM_TO_CHAR(STOPPED)
1997        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1998        CASE_ENUM_TO_CHAR(PREVIEW)
1999        CASE_ENUM_TO_CHAR(RECORD)
2000        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
2001        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
2002        default:
2003            return "Unknown state!";
2004            break;
2005    }
2006#undef CASE_ENUM_TO_CHAR
2007}
2008
2009int Parameters::formatStringToEnum(const char *format) {
2010    return
2011        !format ?
2012            HAL_PIXEL_FORMAT_YCrCb_420_SP :
2013        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2014            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2015        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2016            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2017        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2018            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
2019        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2020            HAL_PIXEL_FORMAT_YV12 :         // YV12
2021        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2022            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
2023        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2024            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
2025        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2026            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
2027        -1;
2028}
2029
2030const char* Parameters::formatEnumToString(int format) {
2031    const char *fmt;
2032    switch(format) {
2033        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2034            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2035            break;
2036        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2037            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2038            break;
2039        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2040            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2041            break;
2042        case HAL_PIXEL_FORMAT_YV12:        // YV12
2043            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2044            break;
2045        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
2046            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2047            break;
2048        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
2049            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2050            break;
2051        case HAL_PIXEL_FORMAT_RAW_SENSOR:
2052            ALOGW("Raw sensor preview format requested.");
2053            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2054            break;
2055        default:
2056            ALOGE("%s: Unknown preview format: %x",
2057                    __FUNCTION__,  format);
2058            fmt = NULL;
2059            break;
2060    }
2061    return fmt;
2062}
2063
2064int Parameters::wbModeStringToEnum(const char *wbMode) {
2065    return
2066        !wbMode ?
2067            ANDROID_CONTROL_AWB_MODE_AUTO :
2068        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2069            ANDROID_CONTROL_AWB_MODE_AUTO :
2070        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2071            ANDROID_CONTROL_AWB_MODE_INCANDESCENT :
2072        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2073            ANDROID_CONTROL_AWB_MODE_FLUORESCENT :
2074        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2075            ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT :
2076        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2077            ANDROID_CONTROL_AWB_MODE_DAYLIGHT :
2078        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2079            ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT :
2080        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2081            ANDROID_CONTROL_AWB_MODE_TWILIGHT :
2082        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2083            ANDROID_CONTROL_AWB_MODE_SHADE :
2084        -1;
2085}
2086
2087const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
2088    switch (wbMode) {
2089        case ANDROID_CONTROL_AWB_MODE_AUTO:
2090            return CameraParameters::WHITE_BALANCE_AUTO;
2091        case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
2092            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
2093        case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
2094            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
2095        case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
2096            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
2097        case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
2098            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
2099        case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
2100            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
2101        case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
2102            return CameraParameters::WHITE_BALANCE_TWILIGHT;
2103        case ANDROID_CONTROL_AWB_MODE_SHADE:
2104            return CameraParameters::WHITE_BALANCE_SHADE;
2105        default:
2106            ALOGE("%s: Unknown AWB mode enum: %d",
2107                    __FUNCTION__, wbMode);
2108            return "unknown";
2109    }
2110}
2111
2112int Parameters::effectModeStringToEnum(const char *effectMode) {
2113    return
2114        !effectMode ?
2115            ANDROID_CONTROL_EFFECT_MODE_OFF :
2116        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2117            ANDROID_CONTROL_EFFECT_MODE_OFF :
2118        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2119            ANDROID_CONTROL_EFFECT_MODE_MONO :
2120        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2121            ANDROID_CONTROL_EFFECT_MODE_NEGATIVE :
2122        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2123            ANDROID_CONTROL_EFFECT_MODE_SOLARIZE :
2124        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2125            ANDROID_CONTROL_EFFECT_MODE_SEPIA :
2126        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2127            ANDROID_CONTROL_EFFECT_MODE_POSTERIZE :
2128        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2129            ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD :
2130        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2131            ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD :
2132        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2133            ANDROID_CONTROL_EFFECT_MODE_AQUA :
2134        -1;
2135}
2136
2137int Parameters::abModeStringToEnum(const char *abMode) {
2138    return
2139        !abMode ?
2140            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2141        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2142            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2143        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2144            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF :
2145        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2146            ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ :
2147        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2148            ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ :
2149        -1;
2150}
2151
2152int Parameters::sceneModeStringToEnum(const char *sceneMode) {
2153    return
2154        !sceneMode ?
2155            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2156        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2157            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2158        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2159            ANDROID_CONTROL_SCENE_MODE_ACTION :
2160        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2161            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2162        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2163            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2164        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2165            ANDROID_CONTROL_SCENE_MODE_NIGHT :
2166        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2167            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2168        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2169            ANDROID_CONTROL_SCENE_MODE_THEATRE :
2170        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2171            ANDROID_CONTROL_SCENE_MODE_BEACH :
2172        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2173            ANDROID_CONTROL_SCENE_MODE_SNOW :
2174        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2175            ANDROID_CONTROL_SCENE_MODE_SUNSET :
2176        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2177            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2178        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2179            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2180        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2181            ANDROID_CONTROL_SCENE_MODE_SPORTS :
2182        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2183            ANDROID_CONTROL_SCENE_MODE_PARTY :
2184        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2185            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2186        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2187            ANDROID_CONTROL_SCENE_MODE_BARCODE:
2188        -1;
2189}
2190
2191Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
2192        const char *flashMode) {
2193    return
2194        !flashMode ?
2195            Parameters::FLASH_MODE_INVALID :
2196        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2197            Parameters::FLASH_MODE_OFF :
2198        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2199            Parameters::FLASH_MODE_AUTO :
2200        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2201            Parameters::FLASH_MODE_ON :
2202        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2203            Parameters::FLASH_MODE_RED_EYE :
2204        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2205            Parameters::FLASH_MODE_TORCH :
2206        Parameters::FLASH_MODE_INVALID;
2207}
2208
2209const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
2210    switch (flashMode) {
2211        case FLASH_MODE_OFF:
2212            return CameraParameters::FLASH_MODE_OFF;
2213        case FLASH_MODE_AUTO:
2214            return CameraParameters::FLASH_MODE_AUTO;
2215        case FLASH_MODE_ON:
2216            return CameraParameters::FLASH_MODE_ON;
2217        case FLASH_MODE_RED_EYE:
2218            return CameraParameters::FLASH_MODE_RED_EYE;
2219        case FLASH_MODE_TORCH:
2220            return CameraParameters::FLASH_MODE_TORCH;
2221        default:
2222            ALOGE("%s: Unknown flash mode enum %d",
2223                    __FUNCTION__, flashMode);
2224            return "unknown";
2225    }
2226}
2227
2228Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
2229        const char *focusMode) {
2230    return
2231        !focusMode ?
2232            Parameters::FOCUS_MODE_INVALID :
2233        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2234            Parameters::FOCUS_MODE_AUTO :
2235        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2236            Parameters::FOCUS_MODE_INFINITY :
2237        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2238            Parameters::FOCUS_MODE_MACRO :
2239        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2240            Parameters::FOCUS_MODE_FIXED :
2241        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2242            Parameters::FOCUS_MODE_EDOF :
2243        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
2244            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
2245        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
2246            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
2247        Parameters::FOCUS_MODE_INVALID;
2248}
2249
2250const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
2251    switch (focusMode) {
2252        case FOCUS_MODE_AUTO:
2253            return CameraParameters::FOCUS_MODE_AUTO;
2254        case FOCUS_MODE_MACRO:
2255            return CameraParameters::FOCUS_MODE_MACRO;
2256        case FOCUS_MODE_CONTINUOUS_VIDEO:
2257            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
2258        case FOCUS_MODE_CONTINUOUS_PICTURE:
2259            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
2260        case FOCUS_MODE_EDOF:
2261            return CameraParameters::FOCUS_MODE_EDOF;
2262        case FOCUS_MODE_INFINITY:
2263            return CameraParameters::FOCUS_MODE_INFINITY;
2264        case FOCUS_MODE_FIXED:
2265            return CameraParameters::FOCUS_MODE_FIXED;
2266        default:
2267            ALOGE("%s: Unknown focus mode enum: %d",
2268                    __FUNCTION__, focusMode);
2269            return "unknown";
2270    }
2271}
2272
2273Parameters::Parameters::lightFxMode_t Parameters::lightFxStringToEnum(
2274        const char *lightFxMode) {
2275    return
2276        !lightFxMode ?
2277            Parameters::LIGHTFX_NONE :
2278        !strcmp(lightFxMode, CameraParameters::LIGHTFX_LOWLIGHT) ?
2279            Parameters::LIGHTFX_LOWLIGHT :
2280        !strcmp(lightFxMode, CameraParameters::LIGHTFX_HDR) ?
2281            Parameters::LIGHTFX_HDR :
2282        Parameters::LIGHTFX_NONE;
2283}
2284
2285status_t Parameters::parseAreas(const char *areasCStr,
2286        Vector<Parameters::Area> *areas) {
2287    static const size_t NUM_FIELDS = 5;
2288    areas->clear();
2289    if (areasCStr == NULL) {
2290        // If no key exists, use default (0,0,0,0,0)
2291        areas->push();
2292        return OK;
2293    }
2294    String8 areasStr(areasCStr);
2295    ssize_t areaStart = areasStr.find("(", 0) + 1;
2296    while (areaStart != 0) {
2297        const char* area = areasStr.string() + areaStart;
2298        char *numEnd;
2299        int vals[NUM_FIELDS];
2300        for (size_t i = 0; i < NUM_FIELDS; i++) {
2301            errno = 0;
2302            vals[i] = strtol(area, &numEnd, 10);
2303            if (errno || numEnd == area) return BAD_VALUE;
2304            area = numEnd + 1;
2305        }
2306        areas->push(Parameters::Area(
2307            vals[0], vals[1], vals[2], vals[3], vals[4]) );
2308        areaStart = areasStr.find("(", areaStart) + 1;
2309    }
2310    return OK;
2311}
2312
2313status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
2314                                      size_t maxRegions,
2315                                      AreaKind areaKind) const {
2316    // Definition of valid area can be found in
2317    // include/camera/CameraParameters.h
2318    if (areas.size() == 0) return BAD_VALUE;
2319    if (areas.size() == 1) {
2320        if (areas[0].left == 0 &&
2321                areas[0].top == 0 &&
2322                areas[0].right == 0 &&
2323                areas[0].bottom == 0 &&
2324                areas[0].weight == 0) {
2325            // Single (0,0,0,0,0) entry is always valid (== driver decides)
2326            return OK;
2327        }
2328    }
2329
2330    // fixed focus can only set (0,0,0,0,0) focus area
2331    if (areaKind == AREA_KIND_FOCUS && focusMode == FOCUS_MODE_FIXED) {
2332        return BAD_VALUE;
2333    }
2334
2335    if (areas.size() > maxRegions) {
2336        ALOGE("%s: Too many areas requested: %zu",
2337                __FUNCTION__, areas.size());
2338        return BAD_VALUE;
2339    }
2340
2341    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2342         a != areas.end(); a++) {
2343        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2344        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2345        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2346        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2347        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2348        if (a->left >= a->right) return BAD_VALUE;
2349        if (a->top >= a->bottom) return BAD_VALUE;
2350    }
2351    return OK;
2352}
2353
2354bool Parameters::boolFromString(const char *boolStr) {
2355    return !boolStr ? false :
2356        !strcmp(boolStr, CameraParameters::TRUE) ? true :
2357        false;
2358}
2359
2360int Parameters::degToTransform(int degrees, bool mirror) {
2361    if (!mirror) {
2362        if (degrees == 0) return 0;
2363        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2364        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2365        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2366    } else {  // Do mirror (horizontal flip)
2367        if (degrees == 0) {           // FLIP_H and ROT_0
2368            return HAL_TRANSFORM_FLIP_H;
2369        } else if (degrees == 90) {   // FLIP_H and ROT_90
2370            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2371        } else if (degrees == 180) {  // FLIP_H and ROT_180
2372            return HAL_TRANSFORM_FLIP_V;
2373        } else if (degrees == 270) {  // FLIP_H and ROT_270
2374            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2375        }
2376    }
2377    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2378    return -1;
2379}
2380
2381int Parameters::cropXToArray(int x) const {
2382    ALOG_ASSERT(x >= 0, "Crop-relative X coordinate = '%d' is out of bounds"
2383                         "(lower = 0)", x);
2384
2385    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2386    ALOG_ASSERT(x < previewCrop.width, "Crop-relative X coordinate = '%d' "
2387                    "is out of bounds (upper = %f)", x, previewCrop.width);
2388
2389    int ret = x + previewCrop.left;
2390
2391    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayWidth),
2392        "Calculated pixel array value X = '%d' is out of bounds (upper = %d)",
2393        ret, fastInfo.arrayWidth);
2394    return ret;
2395}
2396
2397int Parameters::cropYToArray(int y) const {
2398    ALOG_ASSERT(y >= 0, "Crop-relative Y coordinate = '%d' is out of bounds "
2399        "(lower = 0)", y);
2400
2401    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2402    ALOG_ASSERT(y < previewCrop.height, "Crop-relative Y coordinate = '%d' is "
2403                "out of bounds (upper = %f)", y, previewCrop.height);
2404
2405    int ret = y + previewCrop.top;
2406
2407    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayHeight),
2408        "Calculated pixel array value Y = '%d' is out of bounds (upper = %d)",
2409        ret, fastInfo.arrayHeight);
2410
2411    return ret;
2412
2413}
2414
2415int Parameters::normalizedXToCrop(int x) const {
2416    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2417    return (x + 1000) * (previewCrop.width - 1) / 2000;
2418}
2419
2420int Parameters::normalizedYToCrop(int y) const {
2421    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2422    return (y + 1000) * (previewCrop.height - 1) / 2000;
2423}
2424
2425int Parameters::arrayXToCrop(int x) const {
2426    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2427    return x - previewCrop.left;
2428}
2429
2430int Parameters::arrayYToCrop(int y) const {
2431    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2432    return y - previewCrop.top;
2433}
2434
2435int Parameters::cropXToNormalized(int x) const {
2436    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2437    return x * 2000 / (previewCrop.width - 1) - 1000;
2438}
2439
2440int Parameters::cropYToNormalized(int y) const {
2441    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2442    return y * 2000 / (previewCrop.height - 1) - 1000;
2443}
2444
2445int Parameters::arrayXToNormalized(int width) const {
2446    int ret = cropXToNormalized(arrayXToCrop(width));
2447
2448    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of "
2449        "lower bounds %d", ret);
2450    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of "
2451        "upper bounds %d", ret);
2452
2453    // Work-around for HAL pre-scaling the coordinates themselves
2454    if (quirks.meteringCropRegion) {
2455        return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2456    }
2457
2458    return ret;
2459}
2460
2461int Parameters::arrayYToNormalized(int height) const {
2462    int ret = cropYToNormalized(arrayYToCrop(height));
2463
2464    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds"
2465        " %d", ret);
2466    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds"
2467        " %d", ret);
2468
2469    // Work-around for HAL pre-scaling the coordinates themselves
2470    if (quirks.meteringCropRegion) {
2471        return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2472    }
2473
2474    return ret;
2475}
2476
2477int Parameters::normalizedXToArray(int x) const {
2478
2479    // Work-around for HAL pre-scaling the coordinates themselves
2480    if (quirks.meteringCropRegion) {
2481        return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2482    }
2483
2484    return cropXToArray(normalizedXToCrop(x));
2485}
2486
2487int Parameters::normalizedYToArray(int y) const {
2488    // Work-around for HAL pre-scaling the coordinates themselves
2489    if (quirks.meteringCropRegion) {
2490        return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2491    }
2492
2493    return cropYToArray(normalizedYToCrop(y));
2494}
2495
2496status_t Parameters::getFilteredPreviewSizes(Size limit, Vector<Size> *sizes) {
2497    if (info == NULL) {
2498        ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
2499        return NO_INIT;
2500    }
2501    if (sizes == NULL) {
2502        ALOGE("%s: Input size is null", __FUNCTION__);
2503        return BAD_VALUE;
2504    }
2505
2506    const size_t SIZE_COUNT = sizeof(Size) / sizeof(int);
2507    camera_metadata_ro_entry_t availableProcessedSizes =
2508        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, SIZE_COUNT);
2509    if (availableProcessedSizes.count < SIZE_COUNT) return BAD_VALUE;
2510
2511    Size previewSize;
2512    for (size_t i = 0; i < availableProcessedSizes.count; i += SIZE_COUNT) {
2513        previewSize.width = availableProcessedSizes.data.i32[i];
2514        previewSize.height = availableProcessedSizes.data.i32[i+1];
2515            // Need skip the preview sizes that are too large.
2516            if (previewSize.width <= limit.width &&
2517                    previewSize.height <= limit.height) {
2518                sizes->push(previewSize);
2519            }
2520    }
2521    if (sizes->isEmpty()) {
2522        ALOGE("generated preview size list is empty!!");
2523        return BAD_VALUE;
2524    }
2525    return OK;
2526}
2527
2528Parameters::Size Parameters::getMaxSizeForRatio(
2529        float ratio, const int32_t* sizeArray, size_t count) {
2530    ALOG_ASSERT(sizeArray != NULL, "size array shouldn't be NULL");
2531    ALOG_ASSERT(count >= 2 && count % 2 == 0, "count must be a positive even number");
2532
2533    Size maxSize = {0, 0};
2534    for (size_t i = 0; i < count; i += 2) {
2535        if (sizeArray[i] > 0 && sizeArray[i+1] > 0) {
2536            float curRatio = static_cast<float>(sizeArray[i]) / sizeArray[i+1];
2537            if (fabs(curRatio - ratio) < ASPECT_RATIO_TOLERANCE && maxSize.width < sizeArray[i]) {
2538                maxSize.width = sizeArray[i];
2539                maxSize.height = sizeArray[i+1];
2540            }
2541        }
2542    }
2543
2544    if (maxSize.width == 0 || maxSize.height == 0) {
2545        maxSize.width = sizeArray[0];
2546        maxSize.height = sizeArray[1];
2547        ALOGW("Unable to find the size to match the given aspect ratio %f."
2548                "Fall back to %d x %d", ratio, maxSize.width, maxSize.height);
2549    }
2550
2551    return maxSize;
2552}
2553
2554Parameters::CropRegion Parameters::calculateCropRegion(
2555                            Parameters::CropRegion::Outputs outputs) const {
2556
2557    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2558
2559    // Need to convert zoom index into a crop rectangle. The rectangle is
2560    // chosen to maximize its area on the sensor
2561
2562    camera_metadata_ro_entry_t maxDigitalZoom =
2563            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
2564    // For each zoom step by how many pixels more do we change the zoom
2565    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2566            (NUM_ZOOM_STEPS-1);
2567    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2568    // via interpolating zoom step into a zoom ratio
2569    float zoomRatio = 1 + zoomIncrement * zoom;
2570    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2571        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2572        maxDigitalZoom.data.f[0], zoomRatio);
2573
2574    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2575          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2576          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2577          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2578
2579    /*
2580     * Assumption: On the HAL side each stream buffer calculates its crop
2581     * rectangle as follows:
2582     *   cropRect = (zoomLeft, zoomRight,
2583     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
2584     *
2585     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2586     *      (we can then get into trouble if the cropHeight > arrayHeight).
2587     * By selecting the zoomRatio based on the smallest outputRatio, we
2588     * guarantee this will never happen.
2589     */
2590
2591    // Enumerate all possible output sizes, select the one with the smallest
2592    // aspect ratio
2593    float minOutputWidth, minOutputHeight, minOutputRatio;
2594    {
2595        float outputSizes[][2] = {
2596            { static_cast<float>(previewWidth),
2597              static_cast<float>(previewHeight) },
2598            { static_cast<float>(videoWidth),
2599              static_cast<float>(videoHeight) },
2600            { static_cast<float>(jpegThumbSize[0]),
2601              static_cast<float>(jpegThumbSize[1]) },
2602            { static_cast<float>(pictureWidth),
2603              static_cast<float>(pictureHeight) },
2604        };
2605
2606        minOutputWidth = outputSizes[0][0];
2607        minOutputHeight = outputSizes[0][1];
2608        minOutputRatio = minOutputWidth / minOutputHeight;
2609        for (unsigned int i = 0;
2610             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2611             ++i) {
2612
2613            // skip over outputs we don't want to consider for the crop region
2614            if ( !((1 << i) & outputs) ) {
2615                continue;
2616            }
2617
2618            float outputWidth = outputSizes[i][0];
2619            float outputHeight = outputSizes[i][1];
2620            float outputRatio = outputWidth / outputHeight;
2621
2622            if (minOutputRatio > outputRatio) {
2623                minOutputRatio = outputRatio;
2624                minOutputWidth = outputWidth;
2625                minOutputHeight = outputHeight;
2626            }
2627
2628            // and then use this output ratio instead of preview output ratio
2629            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2630                  outputRatio, outputWidth, outputHeight, minOutputRatio);
2631        }
2632    }
2633
2634    /* Ensure that the width/height never go out of bounds
2635     * by scaling across a diffent dimension if an out-of-bounds
2636     * possibility exists.
2637     *
2638     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2639     * calculating the zoomWidth from zoomHeight we'll actually get a
2640     * zoomheight > arrayheight
2641     */
2642    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2643    if (minOutputRatio >= arrayRatio) {
2644        // Adjust the height based on the width
2645        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
2646        zoomHeight = zoomWidth *
2647                minOutputHeight / minOutputWidth;
2648
2649    } else {
2650        // Adjust the width based on the height
2651        zoomHeight = fastInfo.arrayHeight / zoomRatio;
2652        zoomWidth = zoomHeight *
2653                minOutputWidth / minOutputHeight;
2654    }
2655    // centering the zoom area within the active area
2656    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2657    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2658
2659    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2660        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2661
2662
2663    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2664    return crop;
2665}
2666
2667status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)
2668        const {
2669    camera_metadata_ro_entry_t sensorSize =
2670            staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
2671    if (!sensorSize.count) return NO_INIT;
2672
2673    float arrayAspect = static_cast<float>(fastInfo.arrayWidth) /
2674            fastInfo.arrayHeight;
2675    float stillAspect = static_cast<float>(pictureWidth) / pictureHeight;
2676    ALOGV("Array aspect: %f, still aspect: %f", arrayAspect, stillAspect);
2677
2678    // The crop factors from the full sensor array to the still picture crop
2679    // region
2680    float horizCropFactor = 1.f;
2681    float vertCropFactor = 1.f;
2682
2683    /**
2684     * Need to calculate the still image field of view based on the total pixel
2685     * array field of view, and the relative aspect ratios of the pixel array
2686     * and output streams.
2687     *
2688     * Special treatment for quirky definition of crop region and relative
2689     * stream cropping.
2690     */
2691    if (quirks.meteringCropRegion) {
2692        // Use max of preview and video as first crop
2693        float previewAspect = static_cast<float>(previewWidth) / previewHeight;
2694        float videoAspect = static_cast<float>(videoWidth) / videoHeight;
2695        if (videoAspect > previewAspect) {
2696            previewAspect = videoAspect;
2697        }
2698        // First crop sensor to preview aspect ratio
2699        if (arrayAspect < previewAspect) {
2700            vertCropFactor = arrayAspect / previewAspect;
2701        } else {
2702            horizCropFactor = previewAspect / arrayAspect;
2703        }
2704        // Second crop to still aspect ratio
2705        if (stillAspect < previewAspect) {
2706            horizCropFactor *= stillAspect / previewAspect;
2707        } else {
2708            vertCropFactor *= previewAspect / stillAspect;
2709        }
2710    } else {
2711        /**
2712         * Crop are just a function of just the still/array relative aspect
2713         * ratios. Since each stream will maximize its area within the crop
2714         * region, and for FOV we assume a full-sensor crop region, we only ever
2715         * crop the FOV either vertically or horizontally, never both.
2716         */
2717        horizCropFactor = (arrayAspect > stillAspect) ?
2718                (stillAspect / arrayAspect) : 1.f;
2719        vertCropFactor = (arrayAspect < stillAspect) ?
2720                (arrayAspect / stillAspect) : 1.f;
2721    }
2722    ALOGV("Horiz crop factor: %f, vert crop fact: %f",
2723            horizCropFactor, vertCropFactor);
2724    /**
2725     * Basic field of view formula is:
2726     *   angle of view = 2 * arctangent ( d / 2f )
2727     * where d is the physical sensor dimension of interest, and f is
2728     * the focal length. This only applies to rectilinear sensors, for focusing
2729     * at distances >> f, etc.
2730     */
2731    if (horizFov != NULL) {
2732        *horizFov = 180 / M_PI * 2 *
2733                atanf(horizCropFactor * sensorSize.data.f[0] /
2734                        (2 * fastInfo.minFocalLength));
2735    }
2736    if (vertFov != NULL) {
2737        *vertFov = 180 / M_PI * 2 *
2738                atanf(vertCropFactor * sensorSize.data.f[1] /
2739                        (2 * fastInfo.minFocalLength));
2740    }
2741    return OK;
2742}
2743
2744int32_t Parameters::fpsFromRange(int32_t /*min*/, int32_t max) const {
2745    return max;
2746}
2747
2748}; // namespace camera2
2749}; // namespace android
2750