LegacyRequestMapper.java revision 49a1d7b7de171246bb5a644c688ad944ead73062
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
1653e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            if (!compensationRange.inRange(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
261df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        /*
262df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it
263df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin         */
264df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
265df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        // Ignore flash.mode controls unless aeMode == ON
266df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        if (aeMode == CONTROL_AE_MODE_ON) {
267df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            // Flash is OFF by default
268df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            p.setFlashMode(Parameters.FLASH_MODE_OFF);
269df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
270df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            if (flashMode == FLASH_MODE_TORCH &&
271df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                    ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) {
272df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                p.setFlashMode(Parameters.FLASH_MODE_TORCH);
273df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            } else if (flashMode == FLASH_MODE_SINGLE &&
274df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                    ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
275df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                p.setFlashMode(Parameters.FLASH_MODE_ON);
276df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
277df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH &&
278df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
279df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            p.setFlashMode(Parameters.FLASH_MODE_ON);
280df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH &&
281df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) {
282df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            p.setFlashMode(Parameters.FLASH_MODE_AUTO);
283df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE &&
284df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) {
285df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            p.setFlashMode(Parameters.FLASH_MODE_RED_EYE);
286df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else {
287df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            // Default to aeMode == ON, flash = OFF
288df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            p.setFlashMode(Parameters.FLASH_MODE_OFF);
289df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
290df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
291df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
292df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    /**
293df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     * Returns null if the anti-banding mode enum is not supported.
294df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin     */
295df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static String convertAeAntiBandingModeToLegacy(int mode) {
296df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        switch (mode) {
297df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_OFF: {
298df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_OFF;
299df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
300df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_50HZ: {
301df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_50HZ;
302df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
303df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_60HZ: {
304df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_60HZ;
305df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
306df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            case CONTROL_AE_ANTIBANDING_MODE_AUTO: {
307df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return Parameters.ANTIBANDING_AUTO;
308df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
309df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            default: {
310df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin                return null;
311df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            }
312df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
313df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
314df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
315df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
316df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        int[] legacyFps = new int[2];
317df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower();
318df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper();
319df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        return legacyFps;
320df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
321df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
3223e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    /** Return the value set by the key, or the {@code defaultValue} if no value was set. */
323df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    private static <T> T getOrDefault(CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue) {
324df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(r, "r must not be null");
325df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(key, "key must not be null");
326df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        checkNotNull(defaultValue, "defaultValue must not be null");
327df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin
328df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        T value = r.get(key);
329df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        if (value == null) {
330df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            return defaultValue;
331df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        } else {
332df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin            return value;
333df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        }
334df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin    }
3353e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3363e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    /**
3373e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * Return {@code null} if the value is not supported, otherwise return the retrieved key's
3383e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * value from the request (or the default value if it wasn't set).
3393e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     *
3403e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * <p>If the fetched value in the request is equivalent to {@code allowedValue},
3413e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * then omit the warning (e.g. turning off AF lock on a camera
3423e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p>
3433e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     *
3443e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p.
3453e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin     */
3463e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    private static <T> T getIfSupported(
3473e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported,
3483e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            T allowedValue) {
3493e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        T val = getOrDefault(r, key, defaultValue);
3503e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3513e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        if (!isSupported) {
3523e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            if (!Objects.equals(val, allowedValue)) {
3533e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin                Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val);
3543e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            }
3553e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin            return null;
3563e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        }
3573e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin
3583e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin        return val;
3593e280b4bb23be4e5e66ea6381fd63c74fdbd927eIgor Murashkin    }
360df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin}
361