LegacyMetadataMapper.java revision a296fece2b974a11bc624fd67b275863f17df867
14961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin/*
24961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * Copyright (C) 2014 The Android Open Source Project
34961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin *
44961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
54961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * you may not use this file except in compliance with the License.
64961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * You may obtain a copy of the License at
74961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin *
84961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
94961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin *
104961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * Unless required by applicable law or agreed to in writing, software
114961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
124961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * See the License for the specific language governing permissions and
144961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * limitations under the License.
154961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin */
164961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
174961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinpackage android.hardware.camera2.legacy;
184961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
194961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.graphics.ImageFormat;
204961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.Camera;
214961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.Camera.CameraInfo;
224961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.Camera.Size;
234961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.camera2.CameraCharacteristics;
24a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.camera2.CameraDevice;
25a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.camera2.CameraMetadata;
265776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunkimport android.hardware.camera2.CaptureRequest;
275776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunkimport android.hardware.camera2.CaptureResult;
284961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.camera2.impl.CameraMetadataNative;
294961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.camera2.params.StreamConfiguration;
304961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.hardware.camera2.params.StreamConfigurationDuration;
314961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport android.util.Log;
325776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunkimport android.util.Range;
334961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
344961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport java.util.ArrayList;
355776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunkimport java.util.Arrays;
364961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport java.util.List;
37a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport java.util.Objects;
384961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
394961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport static com.android.internal.util.Preconditions.*;
404961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinimport static android.hardware.camera2.CameraCharacteristics.*;
414961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
424961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin/**
434961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * Provide legacy-specific implementations of camera2 metadata for legacy devices, such as the
444961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin * camera characteristics.
454961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin */
464961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkinpublic class LegacyMetadataMapper {
474961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static final String TAG = "LegacyMetadataMapper";
484961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
494961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
504961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    // from graphics.h
514961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;
524961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static final int HAL_PIXEL_FORMAT_BLOB = 0x21;
534961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
541788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    // for metadata
551788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    private static final float LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS = 0.0f;
561788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin
573e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    private static final long APPROXIMATE_CAPTURE_DELAY_MS = 200; // ms
5891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk    private static final long APPROXIMATE_SENSOR_AREA = (1 << 23); // 8mp
593e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    private static final long APPROXIMATE_JPEG_ENCODE_TIME = 600; // ms
603e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    private static final long NS_PER_MS = 1000000;
613e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk
62a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    /*
63a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * Development hijinks: Lie about not supporting certain capabilities
64a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
65a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * - Unblock some CTS tests from running whose main intent is not the metadata itself
66a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
67a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * TODO: Remove these constants and strip out any code that previously relied on them
68a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * being set to true.
69a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     */
70a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static final boolean LIE_ABOUT_FLASH = true;
71a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static final boolean LIE_ABOUT_AE = true;
72a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static final boolean LIE_ABOUT_AF = true;
73a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static final boolean LIE_ABOUT_AWB = true;
74a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
75a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    /**
76a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * Create characteristics for a legacy device by mapping the {@code parameters}
77a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * and {@code info}
78a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
79a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param parameters A non-{@code null} parameters set
80a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param info Camera info with camera facing direction and angle of orientation
81a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
82a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @return static camera characteristics for a camera device
83a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
84a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @throws NullPointerException if any of the args were {@code null}
85a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     */
86a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    public static CameraCharacteristics createCharacteristics(Camera.Parameters parameters,
87a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            CameraInfo info) {
88a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        checkNotNull(parameters, "parameters must not be null");
89a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        checkNotNull(info, "info must not be null");
90a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
91a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        String paramStr = parameters.flatten();
92a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        android.hardware.CameraInfo outerInfo = new android.hardware.CameraInfo();
93a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        outerInfo.info = info;
94a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
95a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        return createCharacteristics(paramStr, outerInfo);
96a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    }
97a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
984961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    /**
994961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * Create characteristics for a legacy device by mapping the {@code parameters}
1004961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * and {@code info}
1014961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     *
1024961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * @param parameters A string parseable by {@link Camera.Parameters#unflatten}
1034961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * @param info Camera info with camera facing direction and angle of orientation
1044961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * @return static camera characteristics for a camera device
1054961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     *
1064961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     * @throws NullPointerException if any of the args were {@code null}
1074961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin     */
1084961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    public static CameraCharacteristics createCharacteristics(String parameters,
1094961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            android.hardware.CameraInfo info) {
1104961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        checkNotNull(parameters, "parameters must not be null");
1114961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        checkNotNull(info, "info must not be null");
1124961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        checkNotNull(info.info, "info.info must not be null");
1134961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1144961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        CameraMetadataNative m = new CameraMetadataNative();
1154961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1164961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        mapCameraInfo(m, info.info);
1174961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1184961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        Camera.Parameters params = Camera.getEmptyParameters();
1194961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        params.unflatten(parameters);
1204961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        mapCameraParameters(m, params);
1214961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1224961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        if (VERBOSE) {
1234961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            Log.v(TAG, "createCharacteristics metadata:");
1244961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            Log.v(TAG, "--------------------------------------------------- (start)");
1254961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            m.dumpToLog();
1264961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            Log.v(TAG, "--------------------------------------------------- (end)");
1274961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        }
1284961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1294961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        return new CameraCharacteristics(m);
1304961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    }
1314961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1324961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static void mapCameraInfo(CameraMetadataNative m, CameraInfo i) {
1334961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        m.set(LENS_FACING, i.facing == CameraInfo.CAMERA_FACING_BACK ?
1344961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                LENS_FACING_BACK : LENS_FACING_FRONT);
1354961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        m.set(SENSOR_ORIENTATION, i.orientation);
1364961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    }
1374961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1384961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static void mapCameraParameters(CameraMetadataNative m, Camera.Parameters p) {
1391788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        m.set(INFO_SUPPORTED_HARDWARE_LEVEL, INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
1404961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        mapStreamConfigs(m, p);
141a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        mapControlAe(m, p);
142a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        mapControlAwb(m, p);
1435776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        mapCapabilities(m, p);
1441788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        mapLens(m, p);
1451788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        mapFlash(m, p);
1464961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        // TODO: map other fields
1474961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    }
1484961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1494961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static void mapStreamConfigs(CameraMetadataNative m, Camera.Parameters p) {
1504961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
1514961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        ArrayList<StreamConfiguration> availableStreamConfigs = new ArrayList<>();
1524961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        /*
1534961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * Implementation-defined (preview, recording, etc) -> use camera1 preview sizes
1544961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * YUV_420_888 cpu callbacks -> use camera1 preview sizes
1554961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * Other preview callbacks (CPU) -> use camera1 preview sizes
1564961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * JPEG still capture -> use camera1 still capture sizes
1574961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         *
1584961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * Use platform-internal format constants here, since StreamConfigurationMap does the
1594961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         * remapping to public format constants.
1604961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin         */
1614961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        List<Size> previewSizes = p.getSupportedPreviewSizes();
1624961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        appendStreamConfig(availableStreamConfigs,
1634961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes);
1644961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        appendStreamConfig(availableStreamConfigs,
1654961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                ImageFormat.YUV_420_888, previewSizes);
1664961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        for (int format : p.getSupportedPreviewFormats()) {
1674961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            if (ImageFormat.isPublicFormat(format)) {
1684961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                appendStreamConfig(availableStreamConfigs, format, previewSizes);
1694961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            } else {
1704961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                /*
1714961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                 *  Do not add any formats unknown to us
1724961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                 * (since it would fail runtime checks in StreamConfigurationMap)
1734961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                 */
1744961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                Log.w(TAG,
1754961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                        String.format("mapStreamConfigs - Skipping non-public format %x", format));
1764961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            }
1774961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        }
1783e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk
1793e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        List<Camera.Size> jpegSizes = p.getSupportedPictureSizes();
1804961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        appendStreamConfig(availableStreamConfigs,
1814961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes());
1824961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        m.set(SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1834961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                availableStreamConfigs.toArray(new StreamConfiguration[0]));
1843e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk
1853e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        // No frame durations available
1863e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        m.set(SCALER_AVAILABLE_MIN_FRAME_DURATIONS, new StreamConfigurationDuration[0]);
1873e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk
1883e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        StreamConfigurationDuration[] jpegStalls =
1893e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk                new StreamConfigurationDuration[jpegSizes.size()];
1903e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        int i = 0;
1915776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        long longestStallDuration = -1;
1923e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        for (Camera.Size s : jpegSizes) {
1935776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            long stallDuration =  calculateJpegStallDuration(s);
1943e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk            jpegStalls[i++] = new StreamConfigurationDuration(HAL_PIXEL_FORMAT_BLOB, s.width,
1955776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                    s.height, stallDuration);
1965776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            if (longestStallDuration < stallDuration) {
1975776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                longestStallDuration = stallDuration;
1985776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
1993e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        }
2003e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        // Set stall durations for jpeg, other formats use default stall duration
2013e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        m.set(SCALER_AVAILABLE_STALL_DURATIONS, jpegStalls);
2025776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
2035776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        m.set(SENSOR_INFO_MAX_FRAME_DURATION, longestStallDuration);
2045776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
2055776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
2065776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    @SuppressWarnings({"unchecked"})
207a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static void mapControlAe(CameraMetadataNative m, Camera.Parameters p) {
208a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
209a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control.aeAvailableTargetFpsRanges
210a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
2115776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        List<int[]> fpsRanges = p.getSupportedPreviewFpsRange();
2125776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (fpsRanges == null) {
2135776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            throw new AssertionError("Supported FPS ranges cannot be null.");
2145776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
2155776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        int rangesSize = fpsRanges.size();
2165776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (rangesSize <= 0) {
2175776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            throw new AssertionError("At least one FPS range must be supported.");
2185776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
2195776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        Range<Integer>[] ranges = new Range[rangesSize];
2205776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        int i = 0;
2215776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        for (int[] r : fpsRanges) {
2225776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            ranges[i++] = Range.create(r[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
2235776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                    r[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
2245776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
2255776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        m.set(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, ranges);
2265776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
227a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
228a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control.aeAvailableAntiBandingModes
229a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
230a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
2315776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        List<String> antiBandingModes = p.getSupportedAntibanding();
2325776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        int antiBandingModesSize = antiBandingModes.size();
2335776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (antiBandingModesSize > 0) {
2345776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            int[] modes = new int[antiBandingModesSize];
2355776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            int j = 0;
2365776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            for (String mode : antiBandingModes) {
2375776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                int convertedMode = convertAntiBandingMode(mode);
2385776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                if (convertedMode == -1) {
2395776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                    Log.w(TAG, "Antibanding mode " + ((mode == null) ? "NULL" : mode) +
2405776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                            " not supported, skipping...");
2415776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                } else {
2425776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                    modes[j++] = convertedMode;
2435776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                }
2445776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
2455776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, Arrays.copyOf(modes, j));
2465776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
247a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
248a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
249a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control.aeAvailableModes
250a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
251a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        List<String> flashModes = p.getSupportedFlashModes();
252a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
253a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        String[] flashModeStrings = new String[] {
254a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Camera.Parameters.FLASH_MODE_AUTO,
255a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Camera.Parameters.FLASH_MODE_ON,
256a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Camera.Parameters.FLASH_MODE_RED_EYE,
257a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                // Map these manually
258a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Camera.Parameters.FLASH_MODE_TORCH,
259a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Camera.Parameters.FLASH_MODE_OFF,
260a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        };
261a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        int[] flashModeInts = new int[] {
262a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                CONTROL_AE_MODE_ON,
263a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                CONTROL_AE_MODE_ON_AUTO_FLASH,
264a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE
265a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        };
266a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        int[] aeAvail = convertStringListToIntArray(flashModes, flashModeStrings, flashModeInts);
267a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
268a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // No flash control -> AE is always on
269a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (aeAvail == null || aeAvail.length == 0) {
270a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            aeAvail = new int[] {
271a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    CONTROL_AE_MODE_ON
272a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            };
273a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
274a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
275a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_FLASH) {
276a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: Remove this branch
277a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            Log.w(TAG, "mapControlAe - lying; saying we only support CONTROL_AE_MODE_ON");
278a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            aeAvail = new int[] {
279a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    CONTROL_AE_MODE_ON
280a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            };
281a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
282a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
283a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        m.set(CONTROL_AE_AVAILABLE_MODES, aeAvail);
284a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    }
285a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
286a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static void mapControlAwb(CameraMetadataNative m, Camera.Parameters p) {
287a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (!LIE_ABOUT_AWB) {
288a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            throw new AssertionError("Not implemented yet");
289a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
2905776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
2915776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
2925776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    private static void mapCapabilities(CameraMetadataNative m, Camera.Parameters p) {
2935776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        int[] capabilities = { REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE };
2945776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        m.set(REQUEST_AVAILABLE_CAPABILITIES, capabilities);
2954961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    }
2964961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin
2971788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    private static void mapLens(CameraMetadataNative m, Camera.Parameters p) {
2981788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        /*
2991788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin         *  We can tell if the lens is fixed focus;
3001788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin         *  but if it's not, we can't tell the minimum focus distance, so leave it null then.
3011788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin         */
3021788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        if (p.getFocusMode() == Camera.Parameters.FOCUS_MODE_FIXED) {
3031788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin            m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS);
3041788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        }
3051788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    }
3061788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin
3071788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    private static void mapFlash(CameraMetadataNative m, Camera.Parameters p) {
3081788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        boolean flashAvailable = false;
3091788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        List<String> supportedFlashModes = p.getSupportedFlashModes();
3101788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        if (supportedFlashModes != null) {
3111788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin            // If only 'OFF' is available, we don't really have flash support
3121788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin            if (!(supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_OFF) &&
3131788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin                    supportedFlashModes.size() == 1)) {
3141788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin                flashAvailable = true;
3151788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin            }
3161788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        }
3171788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin
318a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_FLASH && flashAvailable) {
319a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: remove this branch
320a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            Log.w(TAG, "mapFlash - lying; saying we never support flash");
321a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            flashAvailable = false;
322a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
323a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
3241788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin        m.set(FLASH_INFO_AVAILABLE, flashAvailable);
3251788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin    }
3261788b0466b029dafd728ce8b097d419c132c1b9eIgor Murashkin
3274961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    private static void appendStreamConfig(
3284961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            ArrayList<StreamConfiguration> configs, int format, List<Camera.Size> sizes) {
3294961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        for (Camera.Size size : sizes) {
3304961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            StreamConfiguration config =
3314961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin                    new StreamConfiguration(format, size.width, size.height, /*input*/false);
3324961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin            configs.add(config);
3334961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin        }
3344961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin    }
3353e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk
3363e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    /**
3375776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * Returns -1 if the anti-banding mode string is null, or not supported.
3385776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     */
3395776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    private static int convertAntiBandingMode(final String mode) {
3405776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (mode == null) {
3415776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            return -1;
3425776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
3435776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        switch(mode) {
3445776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case Camera.Parameters.ANTIBANDING_OFF: {
3455776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return CONTROL_AE_ANTIBANDING_MODE_OFF;
3465776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3475776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case Camera.Parameters.ANTIBANDING_50HZ: {
3485776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return CONTROL_AE_ANTIBANDING_MODE_50HZ;
3495776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3505776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case Camera.Parameters.ANTIBANDING_60HZ: {
3515776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return CONTROL_AE_ANTIBANDING_MODE_60HZ;
3525776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3535776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case Camera.Parameters.ANTIBANDING_AUTO: {
3545776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return CONTROL_AE_ANTIBANDING_MODE_AUTO;
3555776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3565776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            default: {
3575776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return -1;
3585776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3595776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
3605776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
3615776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
3625776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    /**
3635776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * Returns null if the anti-banding mode enum is not supported.
3645776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     */
3655776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    private static String convertAntiBandingModeToLegacy(int mode) {
3665776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        switch(mode) {
3675776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case CONTROL_AE_ANTIBANDING_MODE_OFF: {
3685776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return Camera.Parameters.ANTIBANDING_OFF;
3695776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3705776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case CONTROL_AE_ANTIBANDING_MODE_50HZ: {
3715776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return Camera.Parameters.ANTIBANDING_50HZ;
3725776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3735776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case CONTROL_AE_ANTIBANDING_MODE_60HZ: {
3745776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return Camera.Parameters.ANTIBANDING_60HZ;
3755776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3765776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            case CONTROL_AE_ANTIBANDING_MODE_AUTO: {
3775776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return Camera.Parameters.ANTIBANDING_AUTO;
3785776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3795776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            default: {
3805776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                return null;
3815776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            }
3825776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
3835776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
3845776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
3855776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
3865776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
3875776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        int[] legacyFps = new int[2];
3885776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower();
3895776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper();
3905776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        return legacyFps;
3915776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
3925776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
3935776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    /**
3943e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk     * Return the stall duration for a given output jpeg size in nanoseconds.
3953e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk     *
3963e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk     * <p>An 8mp image is chosen to have a stall duration of 0.8 seconds.</p>
3973e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk     */
3983e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    private static long calculateJpegStallDuration(Camera.Size size) {
3993e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        long baseDuration = APPROXIMATE_CAPTURE_DELAY_MS * NS_PER_MS; // 200ms for capture
4003e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        long area = size.width * (long) size.height;
4013e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        long stallPerArea = APPROXIMATE_JPEG_ENCODE_TIME * NS_PER_MS /
4023e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk                APPROXIMATE_SENSOR_AREA; // 600ms stall for 8mp
4033e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk        return baseDuration + area * stallPerArea;
4043e4fed203fe7c945c53c6d6bb9f160932a1d15b3Ruben Brunk    }
4055776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
4065776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    /**
4075776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * Generate capture result metadata from legacy camera parameters.
4085776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     *
4095776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @param params a {@link Camera.Parameters} object to generate metadata from.
4105776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @param request the {@link CaptureRequest} used for this result.
4115776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @param timestamp the timestamp to use for this result in nanoseconds.
4125776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @return a {@link CameraMetadataNative} object containing result metadata.
4135776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     */
4145776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    public static CameraMetadataNative convertResultMetadata(Camera.Parameters params,
4155776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                                                      CaptureRequest request,
4165776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                                                      long timestamp) {
4175776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        CameraMetadataNative result = new CameraMetadataNative();
418a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
419a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
420a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control
421a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
422a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.afState
423a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_AF) {
424a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: Implement autofocus state machine
425a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            result.set(CaptureResult.CONTROL_AF_MODE, request.get(CaptureRequest.CONTROL_AF_MODE));
426a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
427a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
428a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.aeState
429a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_AE) {
430a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // Lie to pass CTS temporarily.
431a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: Implement precapture trigger, after which we can report CONVERGED ourselves
432a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            result.set(CaptureResult.CONTROL_AE_STATE,
433a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    CONTROL_AE_STATE_CONVERGED);
434a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
435a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            result.set(CaptureResult.CONTROL_AE_MODE,
436a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    request.get(CaptureRequest.CONTROL_AE_MODE));
437a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
438a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
439a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.awbLock
440a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        result.set(CaptureResult.CONTROL_AWB_LOCK, params.getAutoWhiteBalanceLock());
441a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
442a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.awbState
443a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_AWB) {
444a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // Lie to pass CTS temporarily.
445a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: CTS needs to be updated not to query this value
446a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // for LIMITED devices unless its guaranteed to be available.
447a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            result.set(CaptureResult.CONTROL_AWB_STATE,
448a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    CameraMetadata.CONTROL_AWB_STATE_CONVERGED);
449a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // TODO: Read the awb mode from parameters instead
450a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            result.set(CaptureResult.CONTROL_AWB_MODE,
451a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    request.get(CaptureRequest.CONTROL_AWB_MODE));
452a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
453a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
454a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
455a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * lens
456a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
457a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // lens.focalLength
4585776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        result.set(CaptureResult.LENS_FOCAL_LENGTH, params.getFocalLength());
459a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
460a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
461a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * sensor
462a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
463a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // sensor.timestamp
4645776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp);
4655776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
4665776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        // TODO: Remaining result metadata tags conversions.
4675776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        return result;
4685776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
4695776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
4705776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    /**
4715776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * Set the legacy parameters using the request metadata.
4725776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     *
4735776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @param request a {@link CaptureRequest} object to generate parameters from.
4745776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     * @param params the a {@link Camera.Parameters} to set parameters in.
4755776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk     */
4765776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    public static void convertRequestMetadata(CaptureRequest request,
4775776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            /*out*/Camera.Parameters params) {
478a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
479a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
480a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control.ae*
481a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
482a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.aeAntibandingMode
4835776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        Integer antiBandingMode = request.get(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE);
4845776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (antiBandingMode != null) {
4855776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            String legacyMode = convertAntiBandingModeToLegacy(antiBandingMode);
4865776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            if (legacyMode != null) params.setAntibanding(legacyMode);
4875776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
4885776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk
489a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.aeTargetFpsRange
4905776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        Range<Integer> aeFpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
4915776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        if (aeFpsRange != null) {
4925776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange);
4935776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk            params.setPreviewFpsRange(legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
4945776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk                    legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
4955776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk        }
496a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
497a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
498a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * control
499a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
500a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.awbLock
501a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        Boolean awbLock = request.get(CaptureRequest.CONTROL_AWB_LOCK);
502a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        params.setAutoWhiteBalanceLock(awbLock == null ? false : awbLock);
503a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    }
504a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
505a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    /**
506a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * Create an int[] from the List<> by using {@code convertFrom} and {@code convertTo}
507a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * as a one-to-one map (via the index).
508a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
509a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * <p>Strings not appearing in {@code convertFrom} are ignored (with a warning);
510a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * strings appearing in {@code convertFrom} but not {@code convertTo} are silently
511a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * dropped.</p>
512a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
513a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param list Source list of strings
514a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param convertFrom Conversion list of strings
515a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param convertTo Conversion list of ints
516a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @return An array of ints where the values correspond to the ones in {@code convertTo}
517a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *         or {@code null} if {@code list} was {@code null}
518a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     */
519a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static int[] convertStringListToIntArray(
520a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            List<String> list, String[] convertFrom, int[] convertTo) {
521a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (list == null) {
522a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            return null;
523a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
524a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
525a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        List<Integer> convertedList = new ArrayList<>(list.size());
526a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
527a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        for (String str : list) {
528a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            int strIndex = getArrayIndex(convertFrom, str);
529a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
530a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // Guard against bad API1 values
531a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            if (strIndex < 0) {
532a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                Log.w(TAG, "Ignoring invalid parameter " + str);
533a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                continue;
534a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            }
535a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
536a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            // Ignore values we can't map into (intentional)
537a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            if (strIndex < convertTo.length) {
538a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                convertedList.add(convertTo[strIndex]);
539a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            }
540a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
541a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
542a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        int[] returnArray = new int[convertedList.size()];
543a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        for (int i = 0; i < returnArray.length; ++i) {
544a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            returnArray[i] = convertedList.get(i);
545a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
546a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
547a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        return returnArray;
548a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    }
549a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
550a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    /** Return the index of {@code needle} in the {@code array}, or else {@code -1} */
551a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    private static <T> int getArrayIndex(T[] array, T needle) {
552a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (needle == null) {
553a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            return -1;
554a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
555a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
556a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        int index = 0;
557a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        for (T elem : array) {
558a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            if (Objects.equals(elem, needle)) {
559a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                return index;
560a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            }
561a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            index++;
562a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
563a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
564a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        return -1;
565a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    }
566a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
567a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    /**
568a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * Create a request template
569a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
570a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param c a non-{@code null} camera characteristics for this camera
571a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @param templateId a non-negative template ID
572a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
573a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @return a non-{@code null} request template
574a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
575a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @throws IllegalArgumentException if {@code templateId} was invalid
576a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     *
577a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     * @see android.hardware.camera2.CameraDevice#TEMPLATE_MANUAL
578a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin     */
579a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin    public static CameraMetadataNative createRequestTemplate(
580a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            CameraCharacteristics c, int templateId) {
581a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (templateId < 0 || templateId > CameraDevice.TEMPLATE_MANUAL) {
582a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            throw new IllegalArgumentException("templateId out of range");
583a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
584a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
585a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        CameraMetadataNative m = new CameraMetadataNative();
586a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
587a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
588a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * NOTE: If adding new code here and it needs to query the static info,
589a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * query the camera characteristics, so we can reuse this for api2 code later
590a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * to create our own templates in the framework
591a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
592a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
593a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        if (LIE_ABOUT_AWB) {
594a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            m.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
595a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        } else {
596a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            throw new AssertionError("Valid control.awbMode not implemented yet");
597a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
598a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
599a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.aeMode
600a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        m.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
601a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // AE is always unconditionally available in API1 devices
602a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
603a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // control.afMode
604a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        {
605a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            Float minimumFocusDistance = c.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE);
606a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
607a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            int afMode;
608a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            if (minimumFocusDistance != null &&
609a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    minimumFocusDistance == LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS) {
610a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                // Cannot control auto-focus with fixed-focus cameras
611a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                afMode = CameraMetadata.CONTROL_AF_MODE_OFF;
612a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            } else {
613a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                // If a minimum focus distance is reported; the camera must have AF
614a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                afMode = CameraMetadata.CONTROL_AF_MODE_AUTO;
615a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            }
616a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
617a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            m.set(CaptureRequest.CONTROL_AF_MODE, afMode);
618a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
619a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
620a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // TODO: map other request template values
621a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        return m;
6225776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk    }
6234961bc88d7bab869a5296789d26fcfa31ad5f644Igor Murashkin}
624