LegacyRequestMapper.java revision 5d2fa0e0b5db09323a706f914bd268a764070425
1df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin/*
2df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * Copyright (C) 2014 The Android Open Source Project
3df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin *
4df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * you may not use this file except in compliance with the License.
6df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * You may obtain a copy of the License at
7df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin *
8df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin *
10df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * See the License for the specific language governing permissions and
14df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * limitations under the License.
15df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin */
16df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
17df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinpackage android.hardware.camera2.legacy;
18df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
19df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.graphics.Rect;
20df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.Camera;
21df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.Camera.Parameters;
22df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.camera2.CameraCharacteristics;
23df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.camera2.CaptureRequest;
24df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.camera2.params.MeteringRectangle;
25df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.hardware.camera2.utils.ListUtils;
26df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.util.Log;
27df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.util.Range;
28df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport android.util.Size;
29df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
30df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport java.util.ArrayList;
31df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport java.util.Arrays;
32df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport java.util.List;
333e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkinimport java.util.Objects;
34df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
35df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport static com.android.internal.util.Preconditions.*;
36df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinimport static android.hardware.camera2.CaptureRequest.*;
37df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
38df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin/**
39df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin * Provide legacy-specific implementations of camera2 CaptureRequest for legacy devices.
40df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin */
41df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkinpublic class LegacyRequestMapper {
42df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static final String TAG = "LegacyRequestMapper";
43df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
44df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
45df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    /**
46df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * Set the legacy parameters using the {@link LegacyRequest legacy request}.
47df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     *
48df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * <p>The legacy request's parameters are changed as a side effect of calling this
49df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * method.</p>
50df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     *
51df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * @param legacyRequest a non-{@code null} legacy request
52df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     */
53df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    public static void convertRequestMetadata(LegacyRequest legacyRequest) {
54df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        CameraCharacteristics characteristics = legacyRequest.characteristics;
55df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        CaptureRequest request = legacyRequest.captureRequest;
56df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        Size previewSize = legacyRequest.previewSize;
57df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        Camera.Parameters params = legacyRequest.parameters;
58df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
597ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
607ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
61df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
62df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         * scaler.cropRegion
63df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
647ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        ParameterUtils.ZoomData zoomData;
65df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        {
667ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            zoomData = ParameterUtils.convertScalerCropRegion(activeArray,
677ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    request.get(SCALER_CROP_REGION),
687ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    previewSize,
697ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    params);
70df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
71df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            if (params.isZoomSupported()) {
727ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                params.setZoom(zoomData.zoomIndex);
73df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            } else if (VERBOSE) {
74df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                Log.v(TAG, "convertRequestToMetadata - zoom is not supported");
75df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
76df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
77df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
78df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
79df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
80df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         * control.ae*
81df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
82df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // control.aeAntibandingMode
83df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        {
84df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        String legacyMode;
85df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            Integer antiBandingMode = request.get(CONTROL_AE_ANTIBANDING_MODE);
86df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            if (antiBandingMode != null) {
87df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                legacyMode = convertAeAntiBandingModeToLegacy(antiBandingMode);
88df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            } else {
89df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                legacyMode = ListUtils.listSelectFirstFrom(params.getSupportedAntibanding(),
90df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                        new String[] {
91df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                            Parameters.ANTIBANDING_AUTO,
92df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                            Parameters.ANTIBANDING_OFF,
93df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                            Parameters.ANTIBANDING_50HZ,
94df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                            Parameters.ANTIBANDING_60HZ,
95df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                        });
96df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
97df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
98df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            if (legacyMode != null) {
99df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                params.setAntibanding(legacyMode);
100df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
101df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
102df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
103df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
1047ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin         * control.aeRegions, afRegions
105df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
106df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        {
1077ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            // aeRegions
1087ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            {
1097ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS);
1107ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                int maxNumMeteringAreas = params.getMaxNumMeteringAreas();
1117ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                List<Camera.Area> meteringAreaList = convertMeteringRegionsToLegacy(
1127ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                        activeArray, zoomData, aeRegions, maxNumMeteringAreas,
1137ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                        /*regionName*/"AE");
114df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
115df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                params.setMeteringAreas(meteringAreaList);
1167ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            }
117df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
1187ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            // afRegions
1197ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            {
1207ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS);
1217ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                int maxNumFocusAreas = params.getMaxNumFocusAreas();
1227ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                List<Camera.Area> focusAreaList = convertMeteringRegionsToLegacy(
1237ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                        activeArray, zoomData, afRegions, maxNumFocusAreas,
1247ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                        /*regionName*/"AF");
1257ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
1267ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                params.setFocusAreas(focusAreaList);
127df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
128df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
129df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
130df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // control.aeTargetFpsRange
131df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        Range<Integer> aeFpsRange = request.get(CONTROL_AE_TARGET_FPS_RANGE);
132df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        if (aeFpsRange != null) {
133df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange);
1347f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk
1357f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            // TODO - Should we enforce that all HAL1 devices must include (30, 30) FPS range?
1367f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            boolean supported = false;
1377f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            for(int[] range : params.getSupportedPreviewFpsRange()) {
1387f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                if (legacyFps[0] == range[0] && legacyFps[1] == range[1]) {
1397f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                    supported = true;
1407f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                    break;
1417f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                }
1427f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            }
1437f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            if (supported) {
1447f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                params.setPreviewFpsRange(legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
1457f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                        legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
1467f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                params.setRecordingHint(false);
1477f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            } else {
1487f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                Log.w(TAG, "Unsupported FPS range set [" + legacyFps[0] + "," + legacyFps[1] + "]");
1497f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk                params.setRecordingHint(true);
1507f2372bd85445967ac6cb8c9519ebd1405aaa233Ruben Brunk            }
151df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
152df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
153df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
154df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         * control
155df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
156df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
1573e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        // control.aeExposureCompensation
1583e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        {
1593e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            Range<Integer> compensationRange =
1603e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
1613e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            int compensation = getOrDefault(request,
1623e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    CONTROL_AE_EXPOSURE_COMPENSATION,
1633e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    /*defaultValue*/0);
1643e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
1655d2fa0e0b5db09323a706f914bd268a764070425Lajos Molnar            if (!compensationRange.contains(compensation)) {
1663e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                Log.w(TAG,
1673e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                        "convertRequestMetadata - control.aeExposureCompensation " +
1683e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                        "is out of range, ignoring value");
1693e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                compensation = 0;
1703e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            }
1713e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
1723e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            params.setExposureCompensation(compensation);
1733e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        }
1743e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
1753e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        // control.aeLock
1763e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        {
1773e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            Boolean aeLock = getIfSupported(request, CONTROL_AE_LOCK, /*defaultValue*/false,
1783e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    params.isAutoExposureLockSupported(),
1793e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    /*allowedValue*/false);
1803e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
1813e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            if (aeLock != null) {
1823e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                params.setAutoExposureLock(aeLock);
1833e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            }
1843e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
18549a1d7b7de171246bb5a644c688ad944ead73062Igor Murashkin            if (VERBOSE) {
18649a1d7b7de171246bb5a644c688ad944ead73062Igor Murashkin                Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock);
18749a1d7b7de171246bb5a644c688ad944ead73062Igor Murashkin            }
18849a1d7b7de171246bb5a644c688ad944ead73062Igor Murashkin
1893e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            // TODO: Don't add control.aeLock to availableRequestKeys if it's not supported
1903e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        }
1913e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
192df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // control.aeMode, flash.mode
193df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        mapAeAndFlashMode(request, /*out*/params);
194df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
195df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // control.awbLock
1963e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        {
1973e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false,
1983e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    params.isAutoWhiteBalanceLockSupported(),
1993e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                    /*allowedValue*/false);
200df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
2013e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            if (awbLock != null) {
2023e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                params.setAutoWhiteBalanceLock(awbLock);
2033e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            }
2043e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
2053e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin         // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported
2063e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        }
207df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
208df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
2097ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin    private static List<Camera.Area> convertMeteringRegionsToLegacy(
2107ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            Rect activeArray, ParameterUtils.ZoomData zoomData,
2117ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) {
2127ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        if (meteringRegions == null || maxNumMeteringAreas <= 0) {
2137ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            if (maxNumMeteringAreas > 0) {
2147ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT);
2157ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            } else {
2167ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                return null;
2177ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            }
2187ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        }
2197ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2207ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        // Add all non-zero weight regions to the list
2217ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        List<MeteringRectangle> meteringRectangleList = new ArrayList<>();
2227ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        for (MeteringRectangle rect : meteringRegions) {
2237ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            if (rect.getMeteringWeight() != MeteringRectangle.METERING_WEIGHT_DONT_CARE) {
2247ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                meteringRectangleList.add(rect);
2257ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            }
2267ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        }
2277ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2287ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        // Ignore any regions beyond our maximum supported count
2297ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        int countMeteringAreas =
2307ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                Math.min(maxNumMeteringAreas, meteringRectangleList.size());
2317ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        List<Camera.Area> meteringAreaList = new ArrayList<>(countMeteringAreas);
2327ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2337ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        for (int i = 0; i < countMeteringAreas; ++i) {
2347ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            MeteringRectangle rect = meteringRectangleList.get(i);
2357ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2367ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            ParameterUtils.MeteringData meteringData =
2377ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    ParameterUtils.convertMeteringRectangleToLegacy(activeArray, rect, zoomData);
2387ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            meteringAreaList.add(meteringData.meteringArea);
2397ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        }
2407ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2417ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        if (maxNumMeteringAreas < meteringRectangleList.size()) {
2427ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            Log.w(TAG,
2437ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    "convertMeteringRegionsToLegacy - Too many requested " + regionName +
2447ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                            " regions, ignoring all beyond the first " + maxNumMeteringAreas);
2457ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        }
2467ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2477ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        if (VERBOSE) {
2487ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin            Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = "
2497ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin                    + ParameterUtils.stringFromAreaList(meteringAreaList));
2507ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        }
2517ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
2527ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin        return meteringAreaList;
2537ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin    }
2547ee78d1ee3ee068897b9313af2ed6446675c1be0Igor Murashkin
255df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static void mapAeAndFlashMode(CaptureRequest r, /*out*/Parameters p) {
256df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        int flashMode = getOrDefault(r, FLASH_MODE, FLASH_MODE_OFF);
257df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        int aeMode = getOrDefault(r, CONTROL_AE_MODE, CONTROL_AE_MODE_ON);
258df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
259df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        List<String> supportedFlashModes = p.getSupportedFlashModes();
260df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
261396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        String flashModeSetting = null;
262396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin
263396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        // Flash is OFF by default, on cameras that support flash
264396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_OFF)) {
265396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            flashModeSetting = Parameters.FLASH_MODE_OFF;
266396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        }
267396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin
268df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
269df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it
270df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
271df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
272df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // Ignore flash.mode controls unless aeMode == ON
273df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        if (aeMode == CONTROL_AE_MODE_ON) {
274396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            if (flashMode == FLASH_MODE_TORCH) {
275396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) {
276396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        flashModeSetting = Parameters.FLASH_MODE_TORCH;
277396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    } else {
278396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == TORCH;" +
279396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                                "camera does not support it");
280396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    }
281396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            } else if (flashMode == FLASH_MODE_SINGLE) {
282396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
283396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    flashModeSetting = Parameters.FLASH_MODE_ON;
284396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                } else {
285396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == SINGLE;" +
286396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                            "camera does not support it");
287396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                }
288396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            } else {
289396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                // Use the default FLASH_MODE_OFF
290396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            }
291396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH) {
292396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
293396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    flashModeSetting = Parameters.FLASH_MODE_ON;
294396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                } else {
295396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_ALWAYS_FLASH;" +
296396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                            "camera does not support it");
297396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                }
298396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH) {
299396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) {
300396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                flashModeSetting = Parameters.FLASH_MODE_AUTO;
301396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            } else {
302396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;" +
303396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        "camera does not support it");
304df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
305396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
306396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) {
307396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    flashModeSetting = Parameters.FLASH_MODE_RED_EYE;
308396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                } else {
309396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH_REDEYE;"
310396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                            + "camera does not support it");
311396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                }
312df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else {
313df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            // Default to aeMode == ON, flash = OFF
314396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        }
315396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin
316396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        if (flashModeSetting != null) {
317396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin            p.setFlashMode(flashModeSetting);
318396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        }
319396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin
320396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin        if (VERBOSE) {
321396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                Log.v(TAG,
322396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        "mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting
323396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        + ", requested (api2) " + flashMode
324396532ffb80f70c336b3564e5bac4c09d3be07ffIgor Murashkin                        + ", supported (api1) " + ListUtils.listToString(supportedFlashModes));
325df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
326df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
327df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
328df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    /**
329df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * Returns null if the anti-banding mode enum is not supported.
330df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     */
331df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static String convertAeAntiBandingModeToLegacy(int mode) {
332df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        switch (mode) {
333df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_OFF: {
334df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_OFF;
335df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
336df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_50HZ: {
337df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_50HZ;
338df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
339df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_60HZ: {
340df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_60HZ;
341df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
342df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_AUTO: {
343df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_AUTO;
344df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
345df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            default: {
346df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return null;
347df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
348df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
349df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
350df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
351df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
352df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        int[] legacyFps = new int[2];
353df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower();
354df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper();
355df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        return legacyFps;
356df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
357df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
3583e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    /** Return the value set by the key, or the {@code defaultValue} if no value was set. */
359df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static <T> T getOrDefault(CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue) {
360df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(r, "r must not be null");
361df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(key, "key must not be null");
362df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(defaultValue, "defaultValue must not be null");
363df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
364df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        T value = r.get(key);
365df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        if (value == null) {
366df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            return defaultValue;
367df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else {
368df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            return value;
369df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
370df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
3713e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3723e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    /**
3733e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * Return {@code null} if the value is not supported, otherwise return the retrieved key's
3743e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * value from the request (or the default value if it wasn't set).
3753e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     *
3763e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * <p>If the fetched value in the request is equivalent to {@code allowedValue},
3773e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * then omit the warning (e.g. turning off AF lock on a camera
3783e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p>
3793e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     *
3803e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p.
3813e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     */
3823e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    private static <T> T getIfSupported(
3833e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported,
3843e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            T allowedValue) {
3853e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        T val = getOrDefault(r, key, defaultValue);
3863e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3873e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        if (!isSupported) {
3883e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            if (!Objects.equals(val, allowedValue)) {
3893e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val);
3903e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            }
3913e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            return null;
3923e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        }
3933e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3943e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        return val;
3953e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    }
396df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin}
397