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