LegacyRequestMapper.java revision 442395751d46aa0f569ad479202a84713a260be0
1/*
2 * Copyright (C) 2014 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
17package android.hardware.camera2.legacy;
18
19import android.graphics.Rect;
20import android.hardware.Camera;
21import android.hardware.Camera.Parameters;
22import android.hardware.camera2.CameraCharacteristics;
23import android.hardware.camera2.CaptureRequest;
24import android.hardware.camera2.params.MeteringRectangle;
25import android.hardware.camera2.utils.ListUtils;
26import android.hardware.camera2.utils.ParamsUtils;
27import android.location.Location;
28import android.util.Log;
29import android.util.Range;
30import android.util.Size;
31
32import java.util.ArrayList;
33import java.util.Arrays;
34import java.util.List;
35import java.util.Objects;
36
37import static com.android.internal.util.Preconditions.*;
38import static android.hardware.camera2.CaptureRequest.*;
39
40/**
41 * Provide legacy-specific implementations of camera2 CaptureRequest for legacy devices.
42 */
43@SuppressWarnings("deprecation")
44public class LegacyRequestMapper {
45    private static final String TAG = "LegacyRequestMapper";
46    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
47
48    private static final byte DEFAULT_JPEG_QUALITY = 85;
49
50    /**
51     * Set the legacy parameters using the {@link LegacyRequest legacy request}.
52     *
53     * <p>The legacy request's parameters are changed as a side effect of calling this
54     * method.</p>
55     *
56     * @param legacyRequest a non-{@code null} legacy request
57     */
58    public static void convertRequestMetadata(LegacyRequest legacyRequest) {
59        CameraCharacteristics characteristics = legacyRequest.characteristics;
60        CaptureRequest request = legacyRequest.captureRequest;
61        Size previewSize = legacyRequest.previewSize;
62        Camera.Parameters params = legacyRequest.parameters;
63
64        Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
65
66        /*
67         * scaler.cropRegion
68         */
69        ParameterUtils.ZoomData zoomData;
70        {
71            zoomData = ParameterUtils.convertScalerCropRegion(activeArray,
72                    request.get(SCALER_CROP_REGION),
73                    previewSize,
74                    params);
75
76            if (params.isZoomSupported()) {
77                params.setZoom(zoomData.zoomIndex);
78            } else if (VERBOSE) {
79                Log.v(TAG, "convertRequestToMetadata - zoom is not supported");
80            }
81        }
82
83        /*
84         * colorCorrection.*
85         */
86        // colorCorrection.aberrationMode
87        {
88            int aberrationMode = ParamsUtils.getOrDefault(request,
89                    COLOR_CORRECTION_ABERRATION_MODE,
90                    /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST);
91
92            if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST) {
93                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
94                        "colorCorrection.aberrationMode = " + aberrationMode);
95            }
96        }
97
98        /*
99         * control.ae*
100         */
101        // control.aeAntibandingMode
102        {
103        String legacyMode;
104            Integer antiBandingMode = request.get(CONTROL_AE_ANTIBANDING_MODE);
105            if (antiBandingMode != null) {
106                legacyMode = convertAeAntiBandingModeToLegacy(antiBandingMode);
107            } else {
108                legacyMode = ListUtils.listSelectFirstFrom(params.getSupportedAntibanding(),
109                        new String[] {
110                            Parameters.ANTIBANDING_AUTO,
111                            Parameters.ANTIBANDING_OFF,
112                            Parameters.ANTIBANDING_50HZ,
113                            Parameters.ANTIBANDING_60HZ,
114                        });
115            }
116
117            if (legacyMode != null) {
118                params.setAntibanding(legacyMode);
119            }
120        }
121
122        /*
123         * control.aeRegions, afRegions
124         */
125        {
126            // aeRegions
127            {
128                // Use aeRegions if available, fall back to using awbRegions if present
129                MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS);
130                if (request.get(CONTROL_AWB_REGIONS) != null) {
131                    Log.w(TAG, "convertRequestMetadata - control.awbRegions setting is not " +
132                            "supported, ignoring value");
133                }
134                int maxNumMeteringAreas = params.getMaxNumMeteringAreas();
135                List<Camera.Area> meteringAreaList = convertMeteringRegionsToLegacy(
136                        activeArray, zoomData, aeRegions, maxNumMeteringAreas,
137                        /*regionName*/"AE");
138
139                // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null).
140                if (maxNumMeteringAreas > 0) {
141                    params.setMeteringAreas(meteringAreaList);
142                }
143            }
144
145            // afRegions
146            {
147                MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS);
148                int maxNumFocusAreas = params.getMaxNumFocusAreas();
149                List<Camera.Area> focusAreaList = convertMeteringRegionsToLegacy(
150                        activeArray, zoomData, afRegions, maxNumFocusAreas,
151                        /*regionName*/"AF");
152
153                // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null).
154                if (maxNumFocusAreas > 0) {
155                    params.setFocusAreas(focusAreaList);
156                }
157            }
158        }
159
160        // control.aeTargetFpsRange
161        Range<Integer> aeFpsRange = request.get(CONTROL_AE_TARGET_FPS_RANGE);
162        if (aeFpsRange != null) {
163            int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange);
164
165            // TODO - Should we enforce that all HAL1 devices must include (30, 30) FPS range?
166            boolean supported = false;
167            for(int[] range : params.getSupportedPreviewFpsRange()) {
168                if (legacyFps[0] == range[0] && legacyFps[1] == range[1]) {
169                    supported = true;
170                    break;
171                }
172            }
173            if (supported) {
174                params.setPreviewFpsRange(legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
175                        legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
176            } else {
177                Log.w(TAG, "Unsupported FPS range set [" + legacyFps[0] + "," + legacyFps[1] + "]");
178            }
179        }
180
181        /*
182         * control
183         */
184
185        // control.aeExposureCompensation
186        {
187            Range<Integer> compensationRange =
188                    characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
189            int compensation = ParamsUtils.getOrDefault(request,
190                    CONTROL_AE_EXPOSURE_COMPENSATION,
191                    /*defaultValue*/0);
192
193            if (!compensationRange.contains(compensation)) {
194                Log.w(TAG,
195                        "convertRequestMetadata - control.aeExposureCompensation " +
196                        "is out of range, ignoring value");
197                compensation = 0;
198            }
199
200            params.setExposureCompensation(compensation);
201        }
202
203        // control.aeLock
204        {
205            Boolean aeLock = getIfSupported(request, CONTROL_AE_LOCK, /*defaultValue*/false,
206                    params.isAutoExposureLockSupported(),
207                    /*allowedValue*/false);
208
209            if (aeLock != null) {
210                params.setAutoExposureLock(aeLock);
211            }
212
213            if (VERBOSE) {
214                Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock);
215            }
216
217            // TODO: Don't add control.aeLock to availableRequestKeys if it's not supported
218        }
219
220        // control.aeMode, flash.mode
221        mapAeAndFlashMode(request, /*out*/params);
222
223        // control.afMode
224        {
225            int afMode = ParamsUtils.getOrDefault(request, CONTROL_AF_MODE,
226                    /*defaultValue*/CONTROL_AF_MODE_OFF);
227            String focusMode = LegacyMetadataMapper.convertAfModeToLegacy(afMode,
228                    params.getSupportedFocusModes());
229
230            if (focusMode != null) {
231                params.setFocusMode(focusMode);
232            }
233
234            if (VERBOSE) {
235                Log.v(TAG, "convertRequestToMetadata - control.afMode "
236                        + afMode + " mapped to " + focusMode);
237            }
238        }
239
240        // control.awbMode
241        {
242            Integer awbMode = getIfSupported(request, CONTROL_AWB_MODE,
243                    /*defaultValue*/CONTROL_AWB_MODE_AUTO,
244                    params.getSupportedWhiteBalance() != null,
245                    /*allowedValue*/CONTROL_AWB_MODE_AUTO);
246
247            String whiteBalanceMode = null;
248            if (awbMode != null) { // null iff AWB is not supported by camera1 api
249                whiteBalanceMode = convertAwbModeToLegacy(awbMode);
250                params.setWhiteBalance(whiteBalanceMode);
251            }
252
253            if (VERBOSE) {
254                Log.v(TAG, "convertRequestToMetadata - control.awbMode "
255                        + awbMode + " mapped to " + whiteBalanceMode);
256            }
257        }
258
259        // control.awbLock
260        {
261            Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false,
262                    params.isAutoWhiteBalanceLockSupported(),
263                    /*allowedValue*/false);
264
265            if (awbLock != null) {
266                params.setAutoWhiteBalanceLock(awbLock);
267            }
268
269         // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported
270        }
271
272        // control.captureIntent
273        {
274            int captureIntent = ParamsUtils.getOrDefault(request,
275                    CONTROL_CAPTURE_INTENT,
276                    /*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW);
277
278            captureIntent = filterSupportedCaptureIntent(captureIntent);
279
280            params.setRecordingHint(
281                    captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD ||
282                    captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
283        }
284
285        // control.videoStabilizationMode
286        {
287            Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE,
288                    /*defaultValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF,
289                    params.isVideoStabilizationSupported(),
290                    /*allowedValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF);
291
292            if (stabMode != null) {
293                params.setVideoStabilization(stabMode == CONTROL_VIDEO_STABILIZATION_MODE_ON);
294            }
295        }
296
297        // lens.focusDistance
298        {
299            boolean infinityFocusSupported =
300                    ListUtils.listContains(params.getSupportedFocusModes(),
301                            Parameters.FOCUS_MODE_INFINITY);
302            Float focusDistance = getIfSupported(request, LENS_FOCUS_DISTANCE,
303                    /*defaultValue*/0f, infinityFocusSupported, /*allowedValue*/0f);
304
305            if (focusDistance == null || focusDistance != 0f) {
306                Log.w(TAG,
307                        "convertRequestToMetadata - Ignoring android.lens.focusDistance "
308                                + infinityFocusSupported + ", only 0.0f is supported");
309            }
310        }
311
312        // control.sceneMode, control.mode
313        {
314            // TODO: Map FACE_PRIORITY scene mode to face detection.
315
316            if (params.getSupportedSceneModes() != null) {
317                int controlMode = ParamsUtils.getOrDefault(request, CONTROL_MODE,
318                    /*defaultValue*/CONTROL_MODE_AUTO);
319                String modeToSet;
320                switch (controlMode) {
321                    case CONTROL_MODE_USE_SCENE_MODE: {
322                        int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE,
323                                /*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
324                        String legacySceneMode = LegacyMetadataMapper.
325                                convertSceneModeToLegacy(sceneMode);
326                        if (legacySceneMode != null) {
327                            modeToSet = legacySceneMode;
328                        } else {
329                            modeToSet = Parameters.SCENE_MODE_AUTO;
330                            Log.w(TAG, "Skipping unknown requested scene mode: " + sceneMode);
331                        }
332                        break;
333                    }
334                    case CONTROL_MODE_AUTO: {
335                        modeToSet = Parameters.SCENE_MODE_AUTO;
336                        break;
337                    }
338                    default: {
339                        Log.w(TAG, "Control mode " + controlMode +
340                                " is unsupported, defaulting to AUTO");
341                        modeToSet = Parameters.SCENE_MODE_AUTO;
342                    }
343                }
344                params.setSceneMode(modeToSet);
345            }
346        }
347
348        // control.effectMode
349        {
350            if (params.getSupportedColorEffects() != null) {
351                int effectMode = ParamsUtils.getOrDefault(request, CONTROL_EFFECT_MODE,
352                    /*defaultValue*/CONTROL_EFFECT_MODE_OFF);
353                String legacyEffectMode = LegacyMetadataMapper.convertEffectModeToLegacy(effectMode);
354                if (legacyEffectMode != null) {
355                    params.setColorEffect(legacyEffectMode);
356                } else {
357                    params.setColorEffect(Parameters.EFFECT_NONE);
358                    Log.w(TAG, "Skipping unknown requested effect mode: " + effectMode);
359                }
360            }
361        }
362
363        /*
364         * sensor
365         */
366
367        // sensor.testPattern
368        {
369            int testPatternMode = ParamsUtils.getOrDefault(request, SENSOR_TEST_PATTERN_MODE,
370                    /*defaultValue*/SENSOR_TEST_PATTERN_MODE_OFF);
371            if (testPatternMode != SENSOR_TEST_PATTERN_MODE_OFF) {
372                Log.w(TAG, "convertRequestToMetadata - ignoring sensor.testPatternMode "
373                        + testPatternMode + "; only OFF is supported");
374            }
375        }
376
377        /*
378         * jpeg.*
379         */
380
381        // jpeg.gpsLocation
382        {
383            Location location = request.get(JPEG_GPS_LOCATION);
384            if (location != null) {
385                if (checkForCompleteGpsData(location)) {
386                    params.setGpsAltitude(location.getAltitude());
387                    params.setGpsLatitude(location.getLatitude());
388                    params.setGpsLongitude(location.getLongitude());
389                    params.setGpsProcessingMethod(location.getProvider().toUpperCase());
390                    params.setGpsTimestamp(location.getTime());
391                } else {
392                    Log.w(TAG, "Incomplete GPS parameters provided in location " + location);
393                }
394            } else {
395                params.removeGpsData();
396            }
397        }
398
399        // jpeg.orientation
400        {
401            int orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
402            params.setRotation(ParamsUtils.getOrDefault(request, JPEG_ORIENTATION, orientation));
403        }
404
405        // jpeg.quality
406        {
407            params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_QUALITY,
408                    DEFAULT_JPEG_QUALITY));
409        }
410
411        // jpeg.thumbnailQuality
412        {
413            params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_THUMBNAIL_QUALITY,
414                    DEFAULT_JPEG_QUALITY));
415        }
416
417        // jpeg.thumbnailSize
418        {
419            List<Camera.Size> sizes = params.getSupportedJpegThumbnailSizes();
420
421            if (sizes != null && sizes.size() > 0) {
422                Size s = request.get(JPEG_THUMBNAIL_SIZE);
423                boolean invalidSize = (s == null) ? false : !ParameterUtils.containsSize(sizes,
424                        s.getWidth(), s.getHeight());
425                if (invalidSize) {
426                    Log.w(TAG, "Invalid JPEG thumbnail size set " + s + ", skipping thumbnail...");
427                }
428                if (s == null || invalidSize) {
429                    // (0,0) = "no thumbnail" in Camera API 1
430                    params.setJpegThumbnailSize(/*width*/0, /*height*/0);
431                } else {
432                    params.setJpegThumbnailSize(s.getWidth(), s.getHeight());
433                }
434            }
435        }
436
437        /*
438         * noiseReduction.*
439         */
440        // noiseReduction.mode
441        {
442            int mode = ParamsUtils.getOrDefault(request,
443                    NOISE_REDUCTION_MODE,
444                    /*defaultValue*/NOISE_REDUCTION_MODE_FAST);
445
446            if (mode != NOISE_REDUCTION_MODE_FAST) {
447                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
448                        "noiseReduction.mode = " + mode);
449            }
450        }
451    }
452
453    private static boolean checkForCompleteGpsData(Location location) {
454        return location != null && location.getProvider() != null && location.getTime() != 0;
455    }
456
457    static int filterSupportedCaptureIntent(int captureIntent) {
458        switch (captureIntent) {
459            case CONTROL_CAPTURE_INTENT_CUSTOM:
460            case CONTROL_CAPTURE_INTENT_PREVIEW:
461            case CONTROL_CAPTURE_INTENT_STILL_CAPTURE:
462            case CONTROL_CAPTURE_INTENT_VIDEO_RECORD:
463            case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT:
464                break;
465            case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG:
466            case CONTROL_CAPTURE_INTENT_MANUAL:
467                captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
468                Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent
469                        + "; default to PREVIEW");
470            default:
471                captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
472                Log.w(TAG, "Unknown control.captureIntent value " + captureIntent
473                        + "; default to PREVIEW");
474        }
475
476        return captureIntent;
477    }
478
479    private static List<Camera.Area> convertMeteringRegionsToLegacy(
480            Rect activeArray, ParameterUtils.ZoomData zoomData,
481            MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) {
482        if (meteringRegions == null || maxNumMeteringAreas <= 0) {
483            if (maxNumMeteringAreas > 0) {
484                return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT);
485            } else {
486                return null;
487            }
488        }
489
490        // Add all non-zero weight regions to the list
491        List<MeteringRectangle> meteringRectangleList = new ArrayList<>();
492        for (MeteringRectangle rect : meteringRegions) {
493            if (rect.getMeteringWeight() != MeteringRectangle.METERING_WEIGHT_DONT_CARE) {
494                meteringRectangleList.add(rect);
495            }
496        }
497
498        // Ignore any regions beyond our maximum supported count
499        int countMeteringAreas =
500                Math.min(maxNumMeteringAreas, meteringRectangleList.size());
501        List<Camera.Area> meteringAreaList = new ArrayList<>(countMeteringAreas);
502
503        for (int i = 0; i < countMeteringAreas; ++i) {
504            MeteringRectangle rect = meteringRectangleList.get(i);
505
506            ParameterUtils.MeteringData meteringData =
507                    ParameterUtils.convertMeteringRectangleToLegacy(activeArray, rect, zoomData);
508            meteringAreaList.add(meteringData.meteringArea);
509        }
510
511        if (maxNumMeteringAreas < meteringRectangleList.size()) {
512            Log.w(TAG,
513                    "convertMeteringRegionsToLegacy - Too many requested " + regionName +
514                            " regions, ignoring all beyond the first " + maxNumMeteringAreas);
515        }
516
517        if (VERBOSE) {
518            Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = "
519                    + ParameterUtils.stringFromAreaList(meteringAreaList));
520        }
521
522        return meteringAreaList;
523    }
524
525    private static void mapAeAndFlashMode(CaptureRequest r, /*out*/Parameters p) {
526        int flashMode = ParamsUtils.getOrDefault(r, FLASH_MODE, FLASH_MODE_OFF);
527        int aeMode = ParamsUtils.getOrDefault(r, CONTROL_AE_MODE, CONTROL_AE_MODE_ON);
528
529        List<String> supportedFlashModes = p.getSupportedFlashModes();
530
531        String flashModeSetting = null;
532
533        // Flash is OFF by default, on cameras that support flash
534        if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_OFF)) {
535            flashModeSetting = Parameters.FLASH_MODE_OFF;
536        }
537
538        /*
539         * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it
540         */
541
542        // Ignore flash.mode controls unless aeMode == ON
543        if (aeMode == CONTROL_AE_MODE_ON) {
544            if (flashMode == FLASH_MODE_TORCH) {
545                    if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) {
546                        flashModeSetting = Parameters.FLASH_MODE_TORCH;
547                    } else {
548                        Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == TORCH;" +
549                                "camera does not support it");
550                    }
551            } else if (flashMode == FLASH_MODE_SINGLE) {
552                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
553                    flashModeSetting = Parameters.FLASH_MODE_ON;
554                } else {
555                    Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == SINGLE;" +
556                            "camera does not support it");
557                }
558            } else {
559                // Use the default FLASH_MODE_OFF
560            }
561        } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH) {
562                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
563                    flashModeSetting = Parameters.FLASH_MODE_ON;
564                } else {
565                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_ALWAYS_FLASH;" +
566                            "camera does not support it");
567                }
568        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH) {
569            if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) {
570                flashModeSetting = Parameters.FLASH_MODE_AUTO;
571            } else {
572                Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;" +
573                        "camera does not support it");
574            }
575        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
576                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) {
577                    flashModeSetting = Parameters.FLASH_MODE_RED_EYE;
578                } else {
579                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH_REDEYE;"
580                            + "camera does not support it");
581                }
582        } else {
583            // Default to aeMode == ON, flash = OFF
584        }
585
586        if (flashModeSetting != null) {
587            p.setFlashMode(flashModeSetting);
588        }
589
590        if (VERBOSE) {
591                Log.v(TAG,
592                        "mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting
593                        + ", requested (api2) " + flashMode
594                        + ", supported (api1) " + ListUtils.listToString(supportedFlashModes));
595        }
596    }
597
598    /**
599     * Returns null if the anti-banding mode enum is not supported.
600     */
601    private static String convertAeAntiBandingModeToLegacy(int mode) {
602        switch (mode) {
603            case CONTROL_AE_ANTIBANDING_MODE_OFF: {
604                return Parameters.ANTIBANDING_OFF;
605            }
606            case CONTROL_AE_ANTIBANDING_MODE_50HZ: {
607                return Parameters.ANTIBANDING_50HZ;
608            }
609            case CONTROL_AE_ANTIBANDING_MODE_60HZ: {
610                return Parameters.ANTIBANDING_60HZ;
611            }
612            case CONTROL_AE_ANTIBANDING_MODE_AUTO: {
613                return Parameters.ANTIBANDING_AUTO;
614            }
615            default: {
616                return null;
617            }
618        }
619    }
620
621    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
622        int[] legacyFps = new int[2];
623        legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower();
624        legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper();
625        return legacyFps;
626    }
627
628    private static String convertAwbModeToLegacy(int mode) {
629        switch (mode) {
630            case CONTROL_AWB_MODE_AUTO:
631                return Camera.Parameters.WHITE_BALANCE_AUTO;
632            case CONTROL_AWB_MODE_INCANDESCENT:
633                return Camera.Parameters.WHITE_BALANCE_INCANDESCENT;
634            case CONTROL_AWB_MODE_FLUORESCENT:
635                return Camera.Parameters.WHITE_BALANCE_FLUORESCENT;
636            case CONTROL_AWB_MODE_WARM_FLUORESCENT:
637                return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT;
638            case CONTROL_AWB_MODE_DAYLIGHT:
639                return Camera.Parameters.WHITE_BALANCE_DAYLIGHT;
640            case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
641                return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT;
642            case CONTROL_AWB_MODE_TWILIGHT:
643                return Camera.Parameters.WHITE_BALANCE_TWILIGHT;
644            default:
645                Log.w(TAG, "convertAwbModeToLegacy - unrecognized control.awbMode" + mode);
646                return Camera.Parameters.WHITE_BALANCE_AUTO;
647        }
648    }
649
650
651    /**
652     * Return {@code null} if the value is not supported, otherwise return the retrieved key's
653     * value from the request (or the default value if it wasn't set).
654     *
655     * <p>If the fetched value in the request is equivalent to {@code allowedValue},
656     * then omit the warning (e.g. turning off AF lock on a camera
657     * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p>
658     *
659     * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p.
660     */
661    private static <T> T getIfSupported(
662            CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported,
663            T allowedValue) {
664        T val = ParamsUtils.getOrDefault(r, key, defaultValue);
665
666        if (!isSupported) {
667            if (!Objects.equals(val, allowedValue)) {
668                Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val);
669            }
670            return null;
671        }
672
673        return val;
674    }
675}
676