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