16d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/* 26d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Copyright 2016 The Android Open Source Project 36d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 46d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Licensed under the Apache License, Version 2.0 (the "License"); 56d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * you may not use this file except in compliance with the License. 66d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * You may obtain a copy of the License at 76d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 86d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * http://www.apache.org/licenses/LICENSE-2.0 96d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Unless required by applicable law or agreed to in writing, software 116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * distributed under the License is distributed on an "AS IS" BASIS, 126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * See the License for the specific language governing permissions and 146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * limitations under the License. 156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpackage com.android.mediaframeworktest.helpers; 186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport junit.framework.Assert; 206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.ImageFormat; 226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.Rect; 236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCharacteristics; 246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraCharacteristics.Key; 256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CameraMetadata; 266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureRequest; 276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.CaptureResult; 286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.camera2.params.StreamConfigurationMap; 296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log; 306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Range; 316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Rational; 326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Size; 336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.lang.reflect.Array; 356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.ArrayList; 366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.Arrays; 376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.Collection; 386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.HashMap; 396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.HashSet; 406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.List; 416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.Set; 426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport static com.android.mediaframeworktest.helpers.AssertHelpers.assertArrayContainsAnyOf; 446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/** 466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Helpers to get common static info out of the camera. 476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Avoid boiler plate by putting repetitive get/set patterns in this class.</p> 496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Attempt to be durable against the camera device having bad or missing metadata 516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * by providing reasonable defaults and logging warnings when that happens.</p> 526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/** 546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (non-Javadoc) 556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @see android.hardware.camera2.cts.helpers.StaticMetadata 566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class StaticMetadata { 586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final String TAG = "StaticMetadata"; 606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int IGNORE_SIZE_CHECK = -1; 616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST = 100000L; // 100us 636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST = 100000000; // 100ms 646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST = 100; 656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST = 800; 666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST = 4; 676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int TONEMAP_MAX_CURVE_POINTS_AT_LEAST = 64; 686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN = -2; 696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX = 2; 706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final Rational CONTROL_AE_COMPENSATION_STEP_DEFAULT = new Rational(1, 2); 716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final byte REQUEST_PIPELINE_MAX_DEPTH_MAX = 8; 726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private static final int MAX_REPROCESS_MAX_CAPTURE_STALL = 4; 736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // TODO: Consider making this work across any metadata object, not just camera characteristics 756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private final CameraCharacteristics mCharacteristics; 766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private final CheckLevel mLevel; 776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private final CameraErrorCollector mCollector; 786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Index with android.control.aeMode 806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public static final String[] AE_MODE_NAMES = new String[] { 816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_MODE_OFF", 826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_MODE_ON", 836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_MODE_ON_AUTO_FLASH", 846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_MODE_ON_ALWAYS_FLASH", 856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_MODE_ON_AUTO_FLASH_REDEYE" 866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }; 876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Index with android.control.afMode 896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public static final String[] AF_MODE_NAMES = new String[] { 906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_OFF", 916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_AUTO", 926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_MACRO", 936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_CONTINUOUS_VIDEO", 946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_CONTINUOUS_PICTURE", 956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_MODE_EDOF" 966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }; 976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Index with android.control.aeState 996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public static final String[] AE_STATE_NAMES = new String[] { 1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_INACTIVE", 1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_SEARCHING", 1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_CONVERGED", 1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_LOCKED", 1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_FLASH_REQUIRED", 1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AE_STATE_PRECAPTURE" 1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }; 1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Index with android.control.afState 1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public static final String[] AF_STATE_NAMES = new String[] { 1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_INACTIVE", 1116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_PASSIVE_SCAN", 1126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_PASSIVE_FOCUSED", 1136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_ACTIVE_SCAN", 1146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_FOCUSED_LOCKED", 1156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_NOT_FOCUSED_LOCKED", 1166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "AF_STATE_PASSIVE_UNFOCUSED" 1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }; 1186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public enum CheckLevel { 1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** Only log warnings for metadata check failures. Execution continues. */ 1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim WARN, 1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Use ErrorCollector to collect the metadata check failures, Execution 1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * continues. 1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim COLLECT, 1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** Assert the metadata check failures. Execution aborts. */ 1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim ASSERT 1296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Construct a new StaticMetadata object. 1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *<p> Default constructor, only log warnings for the static metadata check failures</p> 1356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param characteristics static info for a camera 1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @throws IllegalArgumentException if characteristics was null 1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 1396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public StaticMetadata(CameraCharacteristics characteristics) { 1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim this(characteristics, CheckLevel.WARN, /*collector*/null); 1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Construct a new StaticMetadata object with {@link CameraErrorCollector}. 1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be 1476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * ignored, otherwise, it will be used to log the check failures. 1486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 1496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param characteristics static info for a camera 1516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param collector The {@link CameraErrorCollector} used by this StaticMetadata 1526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @throws IllegalArgumentException if characteristics or collector was null. 1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public StaticMetadata(CameraCharacteristics characteristics, CameraErrorCollector collector) { 1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim this(characteristics, CheckLevel.COLLECT, collector); 1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Construct a new StaticMetadata object with {@link CheckLevel} and 1606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * {@link CameraErrorCollector}. 1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 1626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be 1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * ignored, otherwise, it will be used to log the check failures. 1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 1656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param characteristics static info for a camera 1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param level The {@link CheckLevel} of this StaticMetadata 1686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param collector The {@link CameraErrorCollector} used by this StaticMetadata 1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @throws IllegalArgumentException if characteristics was null or level was 1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * {@link CheckLevel.COLLECT} but collector was null. 1716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public StaticMetadata(CameraCharacteristics characteristics, CheckLevel level, 1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraErrorCollector collector) { 1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (characteristics == null) { 1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("characteristics was null"); 1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (level == CheckLevel.COLLECT && collector == null) { 1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("collector must valid when COLLECT level is set"); 1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mCharacteristics = characteristics; 1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mLevel = level; 1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mCollector = collector; 1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the CameraCharacteristics associated with this StaticMetadata. 1886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return A non-null CameraCharacteristics object 1906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public CameraCharacteristics getCharacteristics() { 1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return mCharacteristics; 1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the hardware level reported by android.info.supportedHardwareLevel 1976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL}. 1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera device is not reporting the hardwareLevel, this 2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * will cause the test to fail.</p> 2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if the device is {@code FULL}, {@code false} otherwise. 2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHardwareLevelFull() { 2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL; 2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the hardware level reported by android.info.supportedHardwareLevel 2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Return the supported hardware level of the device, or fail if no value is reported. 2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return the supported hardware level as a constant defined for 2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}. 2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getHardwareLevelChecked() { 2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer hwLevel = getValueFromKeyNonNull( 2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); 2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hwLevel == null) { 2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.fail("No supported hardware level reported."); 2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return hwLevel; 2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the hardware level reported by android.info.supportedHardwareLevel 2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}. 2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera device is not reporting the hardwareLevel, this 2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * will cause the test to fail.</p> 2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if the device is {@code LEGACY}, {@code false} otherwise. 2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHardwareLevelLegacy() { 2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; 2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the per frame control is supported by the camera device. 2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if per frame control is supported, {@code false} otherwise. 2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isPerFrameControlSupported() { 2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getSyncMaxLatency() == CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL; 2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum number of frames to wait for a request settings being applied 2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN for unknown latency 2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL for per frame control 2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * a positive int otherwise 2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSyncMaxLatency() { 2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer value = getValueFromKeyNonNull(CameraCharacteristics.SYNC_MAX_LATENCY); 2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (value == null) { 2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN; 2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return value; 2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the hardware level reported by android.info.supportedHardwareLevel 2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}. 2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera device is incorrectly reporting the hardwareLevel, this 2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * will always return {@code true}.</p> 2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if the device is {@code LIMITED}, {@code false} otherwise. 2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHardwareLevelLimited() { 2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; 2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Whether or not the hardware level reported by {@code android.info.supportedHardwareLevel} 2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * is at least {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}. 2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera device is incorrectly reporting the hardwareLevel, this 2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * will always return {@code false}.</p> 2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return 2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * {@code true} if the device is {@code LIMITED} or {@code FULL}, 2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * {@code false} otherwise (i.e. LEGACY). 2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHardwareLevelLimitedOrBetter() { 2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer hwLevel = getValueFromKeyNonNull( 2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); 2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hwLevel == null) { 2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Normal. Device could be limited. 2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int hwLevelInt = hwLevel; 2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return hwLevelInt == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL || 2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim hwLevelInt == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; 2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum number of partial result a request can expect 3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return 1 if partial result is not supported. 3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * a integer value larger than 1 if partial result is supported. 3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getPartialResultCount() { 3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer value = mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT); 3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (value == null) { 3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Optional key. Default value is 1 if key is missing. 3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 1; 3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return value; 3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the exposure time value and clamp to the range if needed. 3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param exposure Input exposure time value to check. 3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Exposure value in the legal range. 3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getExposureClampToRange(long exposure) { 3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim long minExposure = getExposureMinimumOrDefault(Long.MAX_VALUE); 3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim long maxExposure = getExposureMaximumOrDefault(Long.MIN_VALUE); 3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (minExposure > SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST) { 3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE, 3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format( 3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "Min value %d is too large, set to maximal legal value %d", 3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST)); 3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST; 3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxExposure < SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST) { 3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE, 3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format( 3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "Max value %d is too small, set to minimal legal value %d", 3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST)); 3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST; 3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return Math.max(minExposure, Math.min(maxExposure, exposure)); 3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if the camera device support focuser. 3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return true if camera device support focuser, false otherwise. 3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean hasFocuser() { 3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (areKeysAvailable(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)) { 3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // LEGACY devices don't have lens.info.minimumFocusDistance, so guard this query 3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return (getMinimumFocusDistanceChecked() > 0); 3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else { 3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Check available AF modes 3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] availableAfModes = mCharacteristics.get( 3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES); 3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (availableAfModes == null) { 3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Assume that if we have an AF mode which doesn't ignore AF trigger, we have a focuser 3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean hasFocuser = false; 3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim loop: for (int mode : availableAfModes) { 3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim switch (mode) { 3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case CameraMetadata.CONTROL_AF_MODE_AUTO: 3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE: 3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO: 3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case CameraMetadata.CONTROL_AF_MODE_MACRO: 3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim hasFocuser = true; 3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim break loop; 3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return hasFocuser; 3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if the camera device has flash unit. 3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return true if flash unit is available, false otherwise. 3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean hasFlash() { 3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getFlashInfoChecked(); 3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get minimum focus distance. 3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return minimum focus distance, 0 if minimum focus distance is invalid. 3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public float getMinimumFocusDistanceChecked() { 3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Float> key = CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE; 3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Float minFocusDistance; 3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * android.lens.info.minimumFocusDistance - required for FULL and MANUAL_SENSOR-capable 3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * devices; optional for all other devices. 3966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 3976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull() || isCapabilitySupported( 3986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) { 3996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFocusDistance = getValueFromKeyNonNull(key); 4006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else { 4016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFocusDistance = mCharacteristics.get(key); 4026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (minFocusDistance == null) { 4056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0.0f; 4066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " minFocusDistance value shouldn't be negative", 4096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFocusDistance >= 0); 4106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (minFocusDistance < 0) { 4116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFocusDistance = 0.0f; 4126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return minFocusDistance; 4156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 4186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get focusDistanceCalibration. 4196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 4206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return focusDistanceCalibration, UNCALIBRATED if value is invalid. 4216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 4226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getFocusDistanceCalibrationChecked() { 4236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION; 4246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer calibration = getValueFromKeyNonNull(key); 4256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (calibration == null) { 4276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED; 4286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value is out of range" , 4316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim calibration >= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED && 4326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim calibration <= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED); 4336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return calibration; 4356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 4386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max AE regions and do sanity check. 4396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 4406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return AE max regions supported by the camera device 4416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 4426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getAeMaxRegionsChecked() { 4436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE); 4446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (regionCount == null) { 4456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 4466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return regionCount; 4486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 4516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max AWB regions and do sanity check. 4526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 4536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return AWB max regions supported by the camera device 4546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 4556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getAwbMaxRegionsChecked() { 4566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB); 4576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (regionCount == null) { 4586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 4596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return regionCount; 4616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 4646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max AF regions and do sanity check. 4656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 4666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return AF max regions supported by the camera device 4676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 4686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getAfMaxRegionsChecked() { 4696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF); 4706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (regionCount == null) { 4716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 4726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return regionCount; 4746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 4766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the available anti-banding modes. 4776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 4786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The array contains available anti-banding modes. 4796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 4806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAeAvailableAntiBandingModesChecked() { 4816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES; 4826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 4836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 4846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean foundAuto = false; 4856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean found50Hz = false; 4866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean found60Hz = false; 4876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int mode : modes) { 4886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "mode value " + mode + " is out if range", 4896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mode >= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF || 4906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mode <= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO); 4916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO) { 4926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim foundAuto = true; 4936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_50HZ) { 4946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim found50Hz = true; 4956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_60HZ) { 4966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim found60Hz = true; 4976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 4996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Must contain AUTO mode or one of 50/60Hz mode. 5006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Either AUTO mode or both 50HZ/60HZ mode should present", 5016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim foundAuto || (found50Hz && found60Hz)); 5026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 5046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 5076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if the antibanding OFF mode is supported. 5086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 5096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return true if antibanding OFF mode is supported, false otherwise. 5106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 5116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isAntiBandingOffModeSupported() { 5126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> antiBandingModes = 5136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Arrays.asList(CameraTestUtils.toObject(getAeAvailableAntiBandingModesChecked())); 5146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return antiBandingModes.contains(CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF); 5166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Boolean getFlashInfoChecked() { 5196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Boolean> key = CameraCharacteristics.FLASH_INFO_AVAILABLE; 5206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Boolean hasFlash = getValueFromKeyNonNull(key); 5216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // In case the failOnKey only gives warning. 5236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hasFlash == null) { 5246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 5256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return hasFlash; 5286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableTestPatternModesChecked() { 5316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 5326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES; 5336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 5346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 5366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 5376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int expectValue = CameraCharacteristics.SENSOR_TEST_PATTERN_MODE_OFF; 5406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer[] boxedModes = CameraTestUtils.toObject(modes); 5416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value must contain OFF mode", 5426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Arrays.asList(boxedModes).contains(expectValue)); 5436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 5456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 5486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available thumbnail sizes and do the sanity check. 5496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 5506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The array of available thumbnail sizes 5516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 5526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size[] getAvailableThumbnailSizesChecked() { 5536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Size[]> key = CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES; 5546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] sizes = getValueFromKeyNonNull(key); 5556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim final List<Size> sizeList = Arrays.asList(sizes); 5566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Size must contain (0, 0). 5586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "size should contain (0, 0)", sizeList.contains(new Size(0, 0))); 5596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Each size must be distinct. 5616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, sizeList); 5626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Must be sorted in ascending order by area, by width if areas are same. 5646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Size> orderedSizes = 5656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.getAscendingOrderSizes(sizeList, /*ascending*/true); 5666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Sizes should be in ascending order: Original " + sizeList.toString() 5676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + ", Expected " + orderedSizes.toString(), orderedSizes.equals(sizeList)); 5686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // TODO: Aspect ratio match, need wait for android.scaler.availableStreamConfigurations 5706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // implementation see b/12958122. 5716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return sizes; 5736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 5766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available focal lengths and do the sanity check. 5776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 5786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The array of available focal lengths 5796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 5806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public float[] getAvailableFocalLengthsChecked() { 5816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS; 5826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim float[] focalLengths = getValueFromKeyNonNull(key); 5836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Array should contain at least one element", focalLengths.length >= 1); 5856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int i = 0; i < focalLengths.length; i++) { 5876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, 5886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format("focalLength[%d] %f should be positive.", i, focalLengths[i]), 5896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim focalLengths[i] > 0); 5906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(focalLengths))); 5926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return focalLengths; 5946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 5956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 5966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 5976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available apertures and do the sanity check. 5986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 5996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The non-null array of available apertures 6006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 6016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public float[] getAvailableAperturesChecked() { 6026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES; 6036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim float[] apertures = getValueFromKeyNonNull(key); 6046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Array should contain at least one element", apertures.length >= 1); 6066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int i = 0; i < apertures.length; i++) { 6086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, 6096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format("apertures[%d] %f should be positive.", i, apertures[i]), 6106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim apertures[i] > 0); 6116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(apertures))); 6136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return apertures; 6156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 6186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check the available hot pixel map modes. 6196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 6206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return the available hot pixel map modes 6216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 6226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableHotPixelModesChecked() { 6236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES; 6246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 6256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 6276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 6286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 6316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull()) { 6326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Full-capability camera devices must support FAST mode", 6336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.HOT_PIXEL_MODE_FAST)); 6346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 6376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST and HIGH_QUALITY mode must be both present or both not present 6386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> coupledModes = Arrays.asList(new Integer[] { 6396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.HOT_PIXEL_MODE_FAST, 6406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.HOT_PIXEL_MODE_HIGH_QUALITY 6416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }); 6426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey( 6436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, " FAST and HIGH_QUALITY mode must both present or both not present", 6446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim containsAllOrNone(modeList, coupledModes)); 6456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, modeList); 6476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, CameraMetadata.HOT_PIXEL_MODE_OFF, 6486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.HOT_PIXEL_MODE_HIGH_QUALITY); 6496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 6516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 6546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check available face detection modes. 6556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 6566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The non-null array of available face detection modes 6576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 6586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableFaceDetectModesChecked() { 6596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES; 6606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 6616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 6636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 6646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 6676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Array should contain OFF mode", 6686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF)); 6696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, modeList); 6706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF, 6716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL); 6726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 6746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 6776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check max face detected count. 6786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 6796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return max number of faces that can be detected 6806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 6816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxFaceCountChecked() { 6826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT; 6836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer count = getValueFromKeyNonNull(key); 6846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (count == null) { 6866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 6876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 6886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> faceDetectModes = 6906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Arrays.asList(CameraTestUtils.toObject(getAvailableFaceDetectModesChecked())); 6916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (faceDetectModes.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF) && 6926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim faceDetectModes.size() == 1) { 6936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value must be 0 if only OFF mode is supported in " 6946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + "availableFaceDetectionModes", count == 0); 6956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else { 6966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int maxFaceCountAtLeast = STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST; 6976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 6986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Legacy mode may support fewer than STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST faces. 6996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLegacy()) { 7006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxFaceCountAtLeast = 1; 7016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value must be no less than " + maxFaceCountAtLeast + " if SIMPLE" 7036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + "or FULL is also supported in availableFaceDetectionModes", 7046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim count >= maxFaceCountAtLeast); 7056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return count; 7086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 7116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check the available tone map modes. 7126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 7136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return the available tone map modes 7146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 7156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableToneMapModesChecked() { 7166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES; 7176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 7186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 7206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 7216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 7246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Camera devices must always support FAST mode", 7256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.TONEMAP_MODE_FAST)); 7266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Qualification check for MANUAL_POSTPROCESSING capability is in 7276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // StaticMetadataTest#testCapabilities 7286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 7306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST and HIGH_QUALITY mode must be both present or both not present 7316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> coupledModes = Arrays.asList(new Integer[] { 7326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.TONEMAP_MODE_FAST, 7336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.TONEMAP_MODE_HIGH_QUALITY 7346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }); 7356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey( 7366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, " FAST and HIGH_QUALITY mode must both present or both not present", 7376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim containsAllOrNone(modeList, coupledModes)); 7386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, modeList); 7406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE, 7416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.TONEMAP_MODE_PRESET_CURVE); 7426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 7446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 7476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check max tonemap curve point. 7486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 7496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Max tonemap curve points. 7506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 7516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxTonemapCurvePointChecked() { 7526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS; 7536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer count = getValueFromKeyNonNull(key); 7546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = 7556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Arrays.asList(CameraTestUtils.toObject(getAvailableToneMapModesChecked())); 7566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean tonemapCurveOutputSupported = 7576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE) || 7586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.TONEMAP_MODE_GAMMA_VALUE) || 7596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.TONEMAP_MODE_PRESET_CURVE); 7606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (count == null) { 7626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (tonemapCurveOutputSupported) { 7636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.fail("Tonemap curve output is supported but MAX_CURVE_POINTS is null"); 7646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 7666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (tonemapCurveOutputSupported) { 7696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Tonemap curve output supported camera device must support " 7706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + "maxCurvePoints >= " + TONEMAP_MAX_CURVE_POINTS_AT_LEAST, 7716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim count >= TONEMAP_MAX_CURVE_POINTS_AT_LEAST); 7726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return count; 7756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 7786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check pixel array size. 7796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 7806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size getPixelArraySizeChecked() { 7816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Size> key = CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE; 7826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size pixelArray = getValueFromKeyNonNull(key); 7836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (pixelArray == null) { 7846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new Size(0, 0); 7856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return pixelArray; 7886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 7896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 7916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check pre-correction active array size. 7926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 7936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Rect getPreCorrectedActiveArraySizeChecked() { 7946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Rect> key = CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE; 7956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Rect activeArray = getValueFromKeyNonNull(key); 7966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 7976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (activeArray == null) { 7986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new Rect(0, 0, 0, 0); 7996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size pixelArraySize = getPixelArraySizeChecked(); 8026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0); 8036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "values width/height are invalid", 8046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim activeArray.width() <= pixelArraySize.getWidth() && 8056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim activeArray.height() <= pixelArraySize.getHeight()); 8066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return activeArray; 8086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 8116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check active array size. 8126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 8136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Rect getActiveArraySizeChecked() { 8146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Rect> key = CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE; 8156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Rect activeArray = getValueFromKeyNonNull(key); 8166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (activeArray == null) { 8186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new Rect(0, 0, 0, 0); 8196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size pixelArraySize = getPixelArraySizeChecked(); 8226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0); 8236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "values width/height are invalid", 8246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim activeArray.width() <= pixelArraySize.getWidth() && 8256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim activeArray.height() <= pixelArraySize.getHeight()); 8266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return activeArray; 8286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 8316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the dimensions to use for RAW16 buffers. 8326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 8336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size getRawDimensChecked() throws Exception { 8346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] targetCaptureSizes = getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR, 8356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StaticMetadata.StreamDirection.Output); 8366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.assertTrue("No capture sizes available for RAW format!", 8376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim targetCaptureSizes.length != 0); 8386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Rect activeArray = getPreCorrectedActiveArraySizeChecked(); 8396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size preCorrectionActiveArraySize = 8406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim new Size(activeArray.width(), activeArray.height()); 8416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size pixelArraySize = getPixelArraySizeChecked(); 8426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.assertTrue("Missing pre-correction active array size", activeArray.width() > 0 && 8436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim activeArray.height() > 0); 8446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.assertTrue("Missing pixel array size", pixelArraySize.getWidth() > 0 && 8456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim pixelArraySize.getHeight() > 0); 8466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] allowedArraySizes = new Size[] { preCorrectionActiveArraySize, 8476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim pixelArraySize }; 8486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return assertArrayContainsAnyOf("Available sizes for RAW format" + 8496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim " must include either the pre-corrected active array size, or the full " + 8506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "pixel array size", targetCaptureSizes, allowedArraySizes); 8516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 8546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the sensitivity value and clamp to the range if needed. 8556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 8566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param sensitivity Input sensitivity value to check. 8576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Sensitivity value in legal range. 8586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 8596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSensitivityClampToRange(int sensitivity) { 8606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int minSensitivity = getSensitivityMinimumOrDefault(Integer.MAX_VALUE); 8616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int maxSensitivity = getSensitivityMaximumOrDefault(Integer.MIN_VALUE); 8626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (minSensitivity > SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST) { 8636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE, 8646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format( 8656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "Min value %d is too large, set to maximal legal value %d", 8666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST)); 8676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST; 8686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxSensitivity < SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST) { 8706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE, 8716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format( 8726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "Max value %d is too small, set to minimal legal value %d", 8736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST)); 8746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST; 8756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return Math.max(minSensitivity, Math.min(maxSensitivity, sensitivity)); 8786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 8816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get maxAnalogSensitivity for a camera device. 8826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 8836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * This is only available for FULL capability device, return 0 if it is unavailable. 8846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 8856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 8866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return maxAnalogSensitivity, 0 if it is not available. 8876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 8886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxAnalogSensitivityChecked() { 8896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY; 8916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer maxAnalogsensitivity = mCharacteristics.get(key); 8926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxAnalogsensitivity == null) { 8936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull()) { 8946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.fail("Full device should report max analog sensitivity"); 8956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 8976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 8986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 8996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int minSensitivity = getSensitivityMinimumOrDefault(); 9006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int maxSensitivity = getSensitivityMaximumOrDefault(); 9016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity 9026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + " should be no larger than max sensitivity " + maxSensitivity, 9036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxAnalogsensitivity <= maxSensitivity); 9046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity 9056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + " should be larger than min sensitivity " + maxSensitivity, 9066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxAnalogsensitivity > minSensitivity); 9076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxAnalogsensitivity; 9096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 9126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get hyperfocalDistance and do the sanity check. 9136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 9146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Note that, this tag is optional, will return -1 if this tag is not 9156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * available. 9166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 9176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return hyperfocalDistance of this device, -1 if this tag is not available. 9196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 9206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public float getHyperfocalDistanceChecked() { 9216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Float> key = CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE; 9226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Float hyperfocalDistance = getValueFromKeyNonNull(key); 9236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hyperfocalDistance == null) { 9246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return -1; 9256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hasFocuser()) { 9286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim float minFocusDistance = getMinimumFocusDistanceChecked(); 9296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, String.format(" hyperfocal distance %f should be in the range of" 9306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + " should be in the range of (%f, %f]", hyperfocalDistance, 0.0f, 9316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFocusDistance), 9326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim hyperfocalDistance > 0 && hyperfocalDistance <= minFocusDistance); 9336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return hyperfocalDistance; 9366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 9396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange. 9406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 9426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead, which is the largest minimum value required to be supported 9436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * by all camera devices.</p> 9446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 9466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 9476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSensitivityMinimumOrDefault() { 9486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getSensitivityMinimumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST); 9496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 9526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange. 9536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 9556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead.</p> 9566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param defaultValue Value to return if no legal value is available 9586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 9596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 9606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSensitivityMinimumOrDefault(int defaultValue) { 9616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer> range = getValueFromKeyNonNull( 9626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE); 9636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (range == null) { 9646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE, 9656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "had no valid minimum value; using default of " + defaultValue); 9666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return defaultValue; 9676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return range.getLower(); 9696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 9726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange. 9736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 9756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead, which is the smallest maximum value required to be supported 9766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * by all camera devices.</p> 9776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 9796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 9806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSensitivityMaximumOrDefault() { 9816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getSensitivityMaximumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST); 9826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 9836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 9846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 9856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange. 9866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 9886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead.</p> 9896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 9906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param defaultValue Value to return if no legal value is available 9916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 9926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 9936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getSensitivityMaximumOrDefault(int defaultValue) { 9946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer> range = getValueFromKeyNonNull( 9956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE); 9966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (range == null) { 9976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE, 9986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "had no valid maximum value; using default of " + defaultValue); 9996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return defaultValue; 10006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return range.getUpper(); 10026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 10056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange. 10066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 10086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead.</p> 10096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param defaultValue Value to return if no legal value is available 10116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 10126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 10136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getExposureMinimumOrDefault(long defaultValue) { 10146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Long> range = getValueFromKeyNonNull( 10156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); 10166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (range == null) { 10176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE, 10186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "had no valid minimum value; using default of " + defaultValue); 10196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return defaultValue; 10206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return range.getLower(); 10226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 10256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange. 10266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 10286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead, which is the largest minimum value required to be supported 10296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * by all camera devices.</p> 10306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 10326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 10336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getExposureMinimumOrDefault() { 10346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getExposureMinimumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST); 10356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 10386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange. 10396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 10416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead.</p> 10426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param defaultValue Value to return if no legal value is available 10446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 10456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 10466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getExposureMaximumOrDefault(long defaultValue) { 10476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Long> range = getValueFromKeyNonNull( 10486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); 10496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (range == null) { 10506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE, 10516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "had no valid maximum value; using default of " + defaultValue); 10526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return defaultValue; 10536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return range.getUpper(); 10556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 10586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange. 10596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera is incorrectly reporting values, log a warning and return 10616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead, which is the smallest maximum value required to be supported 10626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * by all camera devices.</p> 10636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device or the defaultValue otherwise. 10656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 10666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getExposureMaximumOrDefault() { 10676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getExposureMaximumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST); 10686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 10716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * get android.control.availableModes and do the sanity check. 10726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 10736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return available control modes. 10746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 10756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableControlModesChecked() { 10766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> modesKey = CameraCharacteristics.CONTROL_AVAILABLE_MODES; 10776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(modesKey); 10786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 10796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modes = new int[0]; 10806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 10816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 10836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty()); 10846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // All camera device must support AUTO 10866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain AUTO mode", 10876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_MODE_AUTO)); 10886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 10896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean isAeOffSupported = Arrays.asList( 10906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.toObject(getAeAvailableModesChecked())).contains( 10916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_AE_MODE_OFF); 10926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean isAfOffSupported = Arrays.asList( 10936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.toObject(getAfAvailableModesChecked())).contains( 10946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_AF_MODE_OFF); 10956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean isAwbOffSupported = Arrays.asList( 10966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.toObject(getAwbAvailableModesChecked())).contains( 10976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_AWB_MODE_OFF); 10986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isAeOffSupported && isAfOffSupported && isAwbOffSupported) { 10996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // 3A OFF controls are supported, OFF mode must be supported here. 11006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain OFF mode", 11016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_MODE_OFF)); 11026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isSceneModeSupported()) { 11056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain" 11066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + " USE_SCENE_MODE", 11076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_MODE_USE_SCENE_MODE)); 11086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 11116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isSceneModeSupported() { 11146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> availableSceneModes = Arrays.asList( 11156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.toObject(getAvailableSceneModesChecked())); 11166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (availableSceneModes.isEmpty()) { 11186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 11196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // If sceneMode is not supported, camera device will contain single entry: DISABLED. 11226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return availableSceneModes.size() > 1 || 11236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim !availableSceneModes.contains(CameraMetadata.CONTROL_SCENE_MODE_DISABLED); 11246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 11276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get aeAvailableModes and do the sanity check. 11286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 11296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Depending on the check level this class has, for WAR or COLLECT levels, 11306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * If the aeMode list is invalid, return an empty mode array. The the caller doesn't 11316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * have to abort the execution even the aeMode list is invalid.</p> 11326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return AE available modes 11336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 11346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAeAvailableModesChecked() { 11356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> modesKey = CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES; 11366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(modesKey); 11376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 11386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modes = new int[0]; 11396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = new ArrayList<Integer>(); 11416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int mode : modes) { 11426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.add(mode); 11436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty()); 11456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // All camera device must support ON 11476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain ON mode", 11486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON)); 11496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // All camera devices with flash units support ON_AUTO_FLASH and ON_ALWAYS_FLASH 11516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Boolean> flashKey= CameraCharacteristics.FLASH_INFO_AVAILABLE; 11526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Boolean hasFlash = getValueFromKeyNonNull(flashKey); 11536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hasFlash == null) { 11546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim hasFlash = false; 11556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hasFlash) { 11576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean flashModeConsistentWithFlash = 11586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) && 11596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH); 11606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, 11616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "value must contain ON_AUTO_FLASH and ON_ALWAYS_FLASH and when flash is" + 11626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "available", flashModeConsistentWithFlash); 11636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else { 11646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean flashModeConsistentWithoutFlash = 11656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim !(modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) || 11666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH) || 11676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE)); 11686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, 11696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "value must not contain ON_AUTO_FLASH, ON_ALWAYS_FLASH and" + 11706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "ON_AUTO_FLASH_REDEYE when flash is unavailable", 11716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim flashModeConsistentWithoutFlash); 11726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FULL mode camera devices always support OFF mode. 11756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean condition = 11766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim !isHardwareLevelFull() || modeList.contains(CameraMetadata.CONTROL_AE_MODE_OFF); 11776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "Full capability device must have OFF mode", condition); 11786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Boundary check. 11806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int mode : modes) { 11816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(modesKey, "Value " + mode + " is out of bound", 11826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mode >= CameraMetadata.CONTROL_AE_MODE_OFF 11836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim && mode <= CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE); 11846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 11876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 11886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 11896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 11906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available AWB modes and do the sanity check. 11916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 11926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return array that contains available AWB modes, empty array if awbAvailableModes is 11936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * unavailable. 11946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 11956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAwbAvailableModesChecked() { 11966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 11976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES; 11986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] awbModes = getValueFromKeyNonNull(key); 11996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (awbModes == null) { 12016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 12026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(awbModes)); 12056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " All camera devices must support AUTO mode", 12066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modesList.contains(CameraMetadata.CONTROL_AWB_MODE_AUTO)); 12076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull()) { 12086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Full capability camera devices must support OFF mode", 12096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modesList.contains(CameraMetadata.CONTROL_AWB_MODE_OFF)); 12106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return awbModes; 12136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 12166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available AF modes and do the sanity check. 12176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 12186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return array that contains available AF modes, empty array if afAvailableModes is 12196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * unavailable. 12206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 12216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAfAvailableModesChecked() { 12226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 12236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES; 12246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] afModes = getValueFromKeyNonNull(key); 12256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (afModes == null) { 12276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 12286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes)); 12316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 12326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Some LEGACY mode devices do not support AF OFF 12336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " All camera devices must support OFF mode", 12346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modesList.contains(CameraMetadata.CONTROL_AF_MODE_OFF)); 12356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (hasFocuser()) { 12376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Camera devices that have focuser units must support AUTO mode", 12386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modesList.contains(CameraMetadata.CONTROL_AF_MODE_AUTO)); 12396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return afModes; 12426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 12456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get supported raw output sizes and do the check. 12466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 12476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Empty size array if raw output is not supported 12486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 12496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size[] getRawOutputSizesChecked() { 12506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR, 12516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamDirection.Output); 12526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 12556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get supported jpeg output sizes and do the check. 12566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 12576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Empty size array if jpeg output is not supported 12586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 12596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size[] getJpegOutputSizesChecked() { 12606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getAvailableSizesForFormatChecked(ImageFormat.JPEG, 12616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamDirection.Output); 12626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 12656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Used to determine the stream direction for various helpers that look up 12666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * format or size information. 12676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 12686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public enum StreamDirection { 12696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** Stream is used with {@link android.hardware.camera2.CameraDevice#configureOutputs} */ 12706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Output, 12716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** Stream is used with {@code CameraDevice#configureInputs} -- NOT YET PUBLIC */ 12726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Input 12736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 12766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available formats for a given direction. 12776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 12786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param direction The stream direction, input or output. 12796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The formats of the given direction, empty array if no available format is found. 12806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 12816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableFormats(StreamDirection direction) { 12826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<StreamConfigurationMap> key = 12836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP; 12846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamConfigurationMap config = getValueFromKeyNonNull(key); 12856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (config == null) { 12876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 12886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 12906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim switch (direction) { 12916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case Output: 12926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return config.getOutputFormats(); 12936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case Input: 12946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return config.getInputFormats(); 12956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim default: 12966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("direction must be output or input"); 12976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 12996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 13016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get valid output formats for a given input format. 13026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 13036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param inputFormat The input format used to produce the output images. 13046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The output formats for the given input format, empty array if 13056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * no available format is found. 13066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 13076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getValidOutputFormatsForInput(int inputFormat) { 13086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<StreamConfigurationMap> key = 13096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP; 13106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamConfigurationMap config = getValueFromKeyNonNull(key); 13116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (config == null) { 13136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 13146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return config.getValidOutputFormatsForInput(inputFormat); 13176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 13206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available sizes for given format and direction. 13216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 13226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param format The format for the requested size array. 13236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param direction The stream direction, input or output. 13246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The sizes of the given format, empty array if no available size is found. 13256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 13266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size[] getAvailableSizesForFormatChecked(int format, StreamDirection direction) { 13276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getAvailableSizesForFormatChecked(format, direction, 13286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /*fastSizes*/true, /*slowSizes*/true); 13296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 13326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available sizes for given format and direction, and whether to limit to slow or fast 13336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * resolutions. 13346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 13356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param format The format for the requested size array. 13366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param direction The stream direction, input or output. 13376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param fastSizes whether to include getOutputSizes() sizes (generally faster) 13386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param slowSizes whether to include getHighResolutionOutputSizes() sizes (generally slower) 13396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The sizes of the given format, empty array if no available size is found. 13406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 13416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Size[] getAvailableSizesForFormatChecked(int format, StreamDirection direction, 13426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim boolean fastSizes, boolean slowSizes) { 13436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<StreamConfigurationMap> key = 13446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP; 13456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamConfigurationMap config = getValueFromKeyNonNull(key); 13466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (config == null) { 13486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new Size[0]; 13496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] sizes = null; 13526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim switch (direction) { 13546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case Output: 13556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] fastSizeList = null; 13566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] slowSizeList = null; 13576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (fastSizes) { 13586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim fastSizeList = config.getOutputSizes(format); 13596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (slowSizes) { 13616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim slowSizeList = config.getHighResolutionOutputSizes(format); 13626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (fastSizeList != null && slowSizeList != null) { 13646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim sizes = new Size[slowSizeList.length + fastSizeList.length]; 13656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim System.arraycopy(fastSizeList, 0, sizes, 0, fastSizeList.length); 13666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim System.arraycopy(slowSizeList, 0, sizes, fastSizeList.length, slowSizeList.length); 13676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else if (fastSizeList != null) { 13686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim sizes = fastSizeList; 13696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else if (slowSizeList != null) { 13706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim sizes = slowSizeList; 13716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim break; 13736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case Input: 13746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim sizes = config.getInputSizes(format); 13756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim break; 13766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim default: 13776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("direction must be output or input"); 13786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (sizes == null) { 13816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim sizes = new Size[0]; 13826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return sizes; 13856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 13866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 13886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available AE target fps ranges. 13896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 13906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return Empty int array if aeAvailableTargetFpsRanges is invalid. 13916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 13926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim @SuppressWarnings("raw") 13936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Range<Integer>[] getAeAvailableTargetFpsRangesChecked() { 13946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Range<Integer>[]> key = 13956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES; 13966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer>[] fpsRanges = getValueFromKeyNonNull(key); 13976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 13986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (fpsRanges == null) { 13996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new Range[0]; 14006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Round down to 2 boundary if it is not integer times of 2, to avoid array out of bound 14036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // in case the above check fails. 14046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int fpsRangeLength = fpsRanges.length; 14056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int minFps, maxFps; 14066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim long maxFrameDuration = getMaxFrameDurationChecked(); 14076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int i = 0; i < fpsRangeLength; i += 1) { 14086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFps = fpsRanges[i].getLower(); 14096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxFps = fpsRanges[i].getUpper(); 14106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " min fps must be no larger than max fps!", 14116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minFps > 0 && maxFps >= minFps); 14126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim long maxDuration = (long) (1e9 / minFps); 14136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, String.format( 14146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim " the frame duration %d for min fps %d must smaller than maxFrameDuration %d", 14156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxDuration, minFps, maxFrameDuration), maxDuration <= maxFrameDuration); 14166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return fpsRanges; 14186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 14216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the highest supported target FPS range. 14226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Prioritizes maximizing the min FPS, then the max FPS without lowering min FPS. 14236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 14246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Range<Integer> getAeMaxTargetFpsRange() { 14256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer>[] fpsRanges = getAeAvailableTargetFpsRangesChecked(); 14266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer> targetRange = fpsRanges[0]; 14286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Assume unsorted list of target FPS ranges, so use two passes, first maximize min FPS 14296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (Range<Integer> candidateRange : fpsRanges) { 14306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (candidateRange.getLower() > targetRange.getLower()) { 14316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim targetRange = candidateRange; 14326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Then maximize max FPS while not lowering min FPS 14356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (Range<Integer> candidateRange : fpsRanges) { 14366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (candidateRange.getLower() >= targetRange.getLower() && 14376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim candidateRange.getUpper() > targetRange.getUpper()) { 14386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim targetRange = candidateRange; 14396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return targetRange; 14426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 14456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max frame duration. 14466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 14476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return 0 if maxFrameDuration is null 14486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 14496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public long getMaxFrameDurationChecked() { 14506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Long> key = 14516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION; 14526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Long maxDuration = getValueFromKeyNonNull(key); 14536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxDuration == null) { 14556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 14566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxDuration; 14596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 14626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available minimal frame durations for a given format. 14636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 14646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param format One of the format from {@link ImageFormat}. 14656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return HashMap of minimal frame durations for different sizes, empty HashMap 14666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * if availableMinFrameDurations is null. 14676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 14686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public HashMap<Size, Long> getAvailableMinFrameDurationsForFormatChecked(int format) { 14696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim HashMap<Size, Long> minDurationMap = new HashMap<Size, Long>(); 14716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<StreamConfigurationMap> key = 14736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP; 14746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamConfigurationMap config = getValueFromKeyNonNull(key); 14756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (config == null) { 14776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return minDurationMap; 14786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (Size size : getAvailableSizesForFormatChecked(format, 14816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamDirection.Output)) { 14826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim long minFrameDuration = config.getOutputMinFrameDuration(format, size); 14836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (minFrameDuration != 0) { 14856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim minDurationMap.put(new Size(size.getWidth(), size.getHeight()), minFrameDuration); 14866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return minDurationMap; 14906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableEdgeModesChecked() { 14936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES; 14946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] edgeModes = getValueFromKeyNonNull(key); 14956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 14966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (edgeModes == null) { 14976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 14986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 14996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(edgeModes)); 15016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Full device should always include OFF and FAST 15026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull()) { 15036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Full device must contain OFF and FAST edge modes", 15046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.EDGE_MODE_OFF) && 15056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.EDGE_MODE_FAST)); 15066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 15096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST and HIGH_QUALITY mode must be both present or both not present 15106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> coupledModes = Arrays.asList(new Integer[] { 15116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.EDGE_MODE_FAST, 15126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.EDGE_MODE_HIGH_QUALITY 15136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }); 15146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey( 15156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, " FAST and HIGH_QUALITY mode must both present or both not present", 15166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim containsAllOrNone(modeList, coupledModes)); 15176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return edgeModes; 15206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableNoiseReductionModesChecked() { 15236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 15246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES; 15256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] noiseReductionModes = getValueFromKeyNonNull(key); 15266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (noiseReductionModes == null) { 15286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 15296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(noiseReductionModes)); 15326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Full device should always include OFF and FAST 15336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelFull()) { 15346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Full device must contain OFF and FAST noise reduction modes", 15366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.NOISE_REDUCTION_MODE_OFF) && 15376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.NOISE_REDUCTION_MODE_FAST)); 15386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 15416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST and HIGH_QUALITY mode must be both present or both not present 15426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> coupledModes = Arrays.asList(new Integer[] { 15436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.NOISE_REDUCTION_MODE_FAST, 15446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.NOISE_REDUCTION_MODE_HIGH_QUALITY 15456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }); 15466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey( 15476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, " FAST and HIGH_QUALITY mode must both present or both not present", 15486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim containsAllOrNone(modeList, coupledModes)); 15496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return noiseReductionModes; 15516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 15546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get value of key android.control.aeCompensationStep and do the sanity check. 15556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 15566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return default value if the value is null. 15576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 15586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Rational getAeCompensationStepChecked() { 15596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Rational> key = 15606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP; 15616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Rational compensationStep = getValueFromKeyNonNull(key); 15626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (compensationStep == null) { 15646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Return default step. 15656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return CONTROL_AE_COMPENSATION_STEP_DEFAULT; 15666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Legacy devices don't have a minimum step requirement 15696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 15706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim float compensationStepF = 15716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim (float) compensationStep.getNumerator() / compensationStep.getDenominator(); 15726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value must be no more than 1/2", compensationStepF <= 0.5f); 15736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return compensationStep; 15766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 15796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get value of key android.control.aeCompensationRange and do the sanity check. 15806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 15816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return default value if the value is null or malformed. 15826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 15836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public Range<Integer> getAeCompensationRangeChecked() { 15846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Range<Integer>> key = 15856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE; 15866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer> compensationRange = getValueFromKeyNonNull(key); 15876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Rational compensationStep = getAeCompensationStepChecked(); 15886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim float compensationStepF = compensationStep.floatValue(); 15896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim final Range<Integer> DEFAULT_RANGE = Range.create( 15906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN / compensationStepF), 15916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX / compensationStepF)); 15926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim final Range<Integer> ZERO_RANGE = Range.create(0, 0); 15936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (compensationRange == null) { 15946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return ZERO_RANGE; 15956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 15966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 15976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Legacy devices don't have a minimum range requirement 15986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter() && !compensationRange.equals(ZERO_RANGE)) { 15996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " range value must be at least " + DEFAULT_RANGE 16006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + ", actual " + compensationRange + ", compensation step " + compensationStep, 16016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim compensationRange.getLower() <= DEFAULT_RANGE.getLower() && 16026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim compensationRange.getUpper() >= DEFAULT_RANGE.getUpper()); 16036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return compensationRange; 16066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 16096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get availableVideoStabilizationModes and do the sanity check. 16106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 16116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return available video stabilization modes, empty array if it is unavailable. 16126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 16136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableVideoStabilizationModesChecked() { 16146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 16156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES; 16166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 16176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 16196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 16206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 16236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " All device should support OFF mode", 16246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF)); 16256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, 16266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF, 16276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON); 16286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 16306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isVideoStabilizationSupported() { 16336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer[] videoStabModes = 16346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraTestUtils.toObject(getAvailableVideoStabilizationModesChecked()); 16356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return Arrays.asList(videoStabModes).contains( 16366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON); 16376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 16406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get availableOpticalStabilization and do the sanity check. 16416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 16426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return available optical stabilization modes, empty array if it is unavailable. 16436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 16446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableOpticalStabilizationChecked() { 16456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 16466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION; 16476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 16486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 16506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 16516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, 16546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_OFF, 16556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_ON); 16566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 16586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 16616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the scaler's max digital zoom ({@code >= 1.0f}) ratio between crop and active array 16626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return the max zoom ratio, or {@code 1.0f} if the value is unavailable 16636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 16646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public float getAvailableMaxDigitalZoomChecked() { 16656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Float> key = 16666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM; 16676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Float maxZoom = getValueFromKeyNonNull(key); 16696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxZoom == null) { 16706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 1.0f; 16716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " max digital zoom should be no less than 1", 16746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim maxZoom >= 1.0f && !Float.isNaN(maxZoom) && !Float.isInfinite(maxZoom)); 16756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxZoom; 16776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableSceneModesChecked() { 16806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 16816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES; 16826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 16836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 16856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 16866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 16896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FACE_PRIORITY must be included if face detection is supported. 16906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (areKeysAvailable(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT) && 16916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim getMaxFaceCountChecked() > 0) { 16926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " FACE_PRIORITY must be included if face detection is supported", 16936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_SCENE_MODE_FACE_PRIORITY)); 16946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 16976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 16986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 16996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableEffectModesChecked() { 17006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 17016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS; 17026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 17036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 17056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 17066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 17096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // OFF must be included. 17106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " OFF must be included", 17116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.CONTROL_EFFECT_MODE_OFF)); 17126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 17146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 17176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get and check the available color aberration modes 17186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 17196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return the available color aberration modes 17206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 17216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableColorAberrationModesChecked() { 17226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 17236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES; 17246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 17256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 17276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 17286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 17316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " Camera devices must always support either OFF or FAST mode", 17326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF) || 17336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST)); 17346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isHardwareLevelLimitedOrBetter()) { 17366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST and HIGH_QUALITY mode must be both present or both not present 17376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> coupledModes = Arrays.asList(new Integer[] { 17386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST, 17396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY 17406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim }); 17416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey( 17426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, " FAST and HIGH_QUALITY mode must both present or both not present", 17436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim containsAllOrNone(modeList, coupledModes)); 17446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkElementDistinct(key, modeList); 17466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, modes, 17476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF, 17486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY); 17496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 17516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 17546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max pipeline depth and do the sanity check. 17556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 17566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return max pipeline depth, default value if it is not available. 17576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 17586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public byte getPipelineMaxDepthChecked() { 17596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Byte> key = 17606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH; 17616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Byte maxDepth = getValueFromKeyNonNull(key); 17626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxDepth == null) { 17646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return REQUEST_PIPELINE_MAX_DEPTH_MAX; 17656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " max pipeline depth should be no larger than " 17686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim + REQUEST_PIPELINE_MAX_DEPTH_MAX, maxDepth <= REQUEST_PIPELINE_MAX_DEPTH_MAX); 17696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxDepth; 17716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 17746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available lens shading modes. 17756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 17766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableLensShadingModesChecked() { 17776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 17786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SHADING_AVAILABLE_MODES; 17796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 17806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 17816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 17826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 17856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // FAST must be included. 17866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " FAST must be included", 17876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.SHADING_MODE_FAST)); 17886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isCapabilitySupported( 17906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING)) { 17916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " OFF must be included for MANUAL_POST_PROCESSING devices", 17926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.SHADING_MODE_OFF)); 17936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 17956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 17966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 17976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 17986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available lens shading map modes. 17996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 18006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int[] getAvailableLensShadingMapModesChecked() { 18016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 18026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES; 18036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] modes = getValueFromKeyNonNull(key); 18046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (modes == null) { 18056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new int[0]; 18066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes)); 18096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (isCapabilitySupported( 18116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW)) { 18126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " ON must be included for RAW capability devices", 18136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim modeList.contains(CameraMetadata.STATISTICS_LENS_SHADING_MAP_MODE_ON)); 18146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return modes; 18166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 18206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get available capabilities and do the sanity check. 18216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return reported available capabilities list, empty list if the value is unavailable. 18236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 18246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public List<Integer> getAvailableCapabilitiesChecked() { 18256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<int[]> key = 18266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES; 18276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int[] availableCaps = getValueFromKeyNonNull(key); 18286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> capList; 18296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (availableCaps == null) { 18316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return new ArrayList<Integer>(); 18326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkArrayValuesInRange(key, availableCaps, 18356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, 18366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO); 18376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim capList = Arrays.asList(CameraTestUtils.toObject(availableCaps)); 18386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return capList; 18396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 18426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether the current device supports a capability or not. 18436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param capability (non-negative) 18456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if the capability is supported, {@code false} otherwise. 18476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @throws IllegalArgumentException if {@code capability} was negative 18496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES 18516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 18526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isCapabilitySupported(int capability) { 18536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (capability < 0) { 18546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("capability must be non-negative"); 18556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> availableCapabilities = getAvailableCapabilitiesChecked(); 18586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return availableCapabilities.contains(capability); 18606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 18636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available characteristics keys 18646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getKeys}. 18656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then querying for this key from a characteristics 18676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * object will always return a non-{@code null} value.</p> 18686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys collection of camera characteristics keys 18706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all characteristics keys are available 18716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 18726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areCharacteristicsKeysAvailable( 18736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Collection<Key<?>> keys) { 18746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return mCharacteristics.getKeys().containsAll(keys); 18756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 18786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available result keys 18796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}. 18806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then querying for this key from a result 18826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * object will almost always return a non-{@code null} value.</p> 18836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>In some cases (e.g. lens shading map), the request must have additional settings 18856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * configured in order for the key to correspond to a value.</p> 18866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys collection of capture result keys 18886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all result keys are available 18896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 18906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areResultKeysAvailable(Collection<CaptureResult.Key<?>> keys) { 18916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return mCharacteristics.getAvailableCaptureResultKeys().containsAll(keys); 18926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 18936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 18946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 18956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available request keys 18966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}. 18976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 18986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then setting this key in the request builder 18996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * may have some effect (and if it's {@code false}, then the camera device will 19006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * definitely ignore it).</p> 19016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>In some cases (e.g. manual control of exposure), other keys must be also be set 19036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * in order for a key to take effect (e.g. control.mode set to OFF).</p> 19046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys collection of capture request keys 19066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all result keys are available 19076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areRequestKeysAvailable(Collection<CaptureRequest.Key<?>> keys) { 19096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return mCharacteristics.getAvailableCaptureRequestKeys().containsAll(keys); 19106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 19136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available characteristics keys 19146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getKeys}. 19156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then querying for this key from a characteristics 19176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * object will always return a non-{@code null} value.</p> 19186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys one or more camera characteristic keys 19206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all characteristics keys are available 19216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim @SafeVarargs 19236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areKeysAvailable(Key<?>... keys) { 19246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areCharacteristicsKeysAvailable(Arrays.asList(keys)); 19256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 19286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available result keys 19296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}. 19306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then querying for this key from a result 19326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * object will almost always return a non-{@code null} value.</p> 19336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>In some cases (e.g. lens shading map), the request must have additional settings 19356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * configured in order for the key to correspond to a value.</p> 19366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys one or more capture result keys 19386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all result keys are available 19396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim @SafeVarargs 19416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areKeysAvailable(CaptureResult.Key<?>... keys) { 19426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areResultKeysAvailable(Arrays.asList(keys)); 19436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 19466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine whether or not all the {@code keys} are available request keys 19476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}. 19486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If this returns {@code true}, then setting this key in the request builder 19506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * may have some effect (and if it's {@code false}, then the camera device will 19516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * definitely ignore it).</p> 19526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>In some cases (e.g. manual control of exposure), other keys must be also be set 19546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * in order for a key to take effect (e.g. control.mode set to OFF).</p> 19556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param keys one or more capture request keys 19576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return whether or not all result keys are available 19586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim @SafeVarargs 19606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public final boolean areKeysAvailable(CaptureRequest.Key<?>... keys) { 19616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areRequestKeysAvailable(Arrays.asList(keys)); 19626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /* 19656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support AE lock control 19666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if AE lock control is supported 19686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isAeLockSupported() { 19706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getValueFromKeyNonNull(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE); 19716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /* 19746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support AWB lock control 19756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if AWB lock control is supported 19776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isAwbLockSupported() { 19796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getValueFromKeyNonNull(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE); 19806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /* 19846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support manual lens shading map control 19856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if manual lens shading map control is supported 19876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isManualLensShadingMapSupported() { 19896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.SHADING_MODE); 19906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 19916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 19926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 19936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support manual color correction control 19946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 19956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if manual color correction control is supported 19966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 19976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isColorCorrectionSupported() { 19986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_MODE); 19996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support manual tone mapping control 20036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if manual tone mapping control is supported 20056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isManualToneMapSupported() { 20076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.TONEMAP_MODE); 20086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support manual color aberration control 20126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if manual color aberration control is supported 20146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isManualColorAberrationControlSupported() { 20166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE); 20176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support edge mode control 20216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if edge mode control is supported 20236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isEdgeModeControlSupported() { 20256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.EDGE_MODE); 20266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support hot pixel mode control 20306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if hot pixel mode control is supported 20326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHotPixelMapModeControlSupported() { 20346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.HOT_PIXEL_MODE); 20356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Determine if camera device support noise reduction mode control 20396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return {@code true} if noise reduction mode control is supported 20416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isNoiseReductionModeControlSupported() { 20436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE); 20446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max number of output raw streams and do the basic sanity check. 20486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return reported max number of raw output stream 20506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxNumOutputStreamsRawChecked() { 20526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer maxNumStreams = 20536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW); 20546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxNumStreams == null) 20556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 20566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxNumStreams; 20576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max number of output processed streams and do the basic sanity check. 20616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return reported max number of processed output stream 20636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxNumOutputStreamsProcessedChecked() { 20656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer maxNumStreams = 20666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC); 20676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxNumStreams == null) 20686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 20696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxNumStreams; 20706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get max number of output stalling processed streams and do the basic sanity check. 20746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 20756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return reported max number of stalling processed output stream 20766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxNumOutputStreamsProcessedStallChecked() { 20786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer maxNumStreams = 20796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING); 20806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (maxNumStreams == null) 20816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return 0; 20826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return maxNumStreams; 20836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 20866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get lens facing and do the sanity check 20876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return lens facing, return default value (BACK) if value is unavailable. 20886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 20896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getLensFacingChecked() { 20906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = 20916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.LENS_FACING; 20926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer facing = getValueFromKeyNonNull(key); 20936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (facing == null) { 20956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return CameraCharacteristics.LENS_FACING_BACK; 20966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 20976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 20986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value is out of range ", 20996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim facing >= CameraCharacteristics.LENS_FACING_FRONT && 21006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim facing <= CameraCharacteristics.LENS_FACING_BACK); 21016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return facing; 21026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get maxCaptureStall frames or default value (if value doesn't exist) 21066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return maxCaptureStall frames or default value. 21076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 21086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getMaxCaptureStallOrDefault() { 21096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = 21106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL; 21116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer value = getValueFromKeyNonNull(key); 21126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (value == null) { 21146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return MAX_REPROCESS_MAX_CAPTURE_STALL; 21156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value is out of range ", 21186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value >= 0 && 21196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value <= MAX_REPROCESS_MAX_CAPTURE_STALL); 21206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return value; 21226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the scaler's cropping type (center only or freeform) 21266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return cropping type, return default value (CENTER_ONLY) if value is unavailable 21276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 21286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public int getScalerCroppingTypeChecked() { 21296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Key<Integer> key = 21306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.SCALER_CROPPING_TYPE; 21316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Integer value = getValueFromKeyNonNull(key); 21326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (value == null) { 21346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY; 21356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, " value is out of range ", 21386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value >= CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY && 21396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value <= CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM); 21406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return value; 21426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if the constrained high speed video is supported by the camera device. 21466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * The high speed FPS ranges and sizes are sanitized in 21476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * ExtendedCameraCharacteristicsTest#testConstrainedHighSpeedCapability. 21486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 21496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return true if the constrained high speed video is supported, false otherwise. 21506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 21516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isConstrainedHighSpeedVideoSupported() { 21526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> availableCapabilities = getAvailableCapabilitiesChecked(); 21536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return (availableCapabilities.contains( 21546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO)); 21556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if high speed video is supported (HIGH_SPEED_VIDEO scene mode is 21596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * supported, supported high speed fps ranges and sizes are valid). 21606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 21616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return true if high speed video is supported. 21626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 21636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isHighSpeedVideoSupported() { 21646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim List<Integer> sceneModes = 21656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Arrays.asList(CameraTestUtils.toObject(getAvailableSceneModesChecked())); 21666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (sceneModes.contains(CameraCharacteristics.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO)) { 21676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim StreamConfigurationMap config = 21686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 21696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (config == null) { 21706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 21716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Size[] availableSizes = config.getHighSpeedVideoSizes(); 21736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (availableSizes.length == 0) { 21746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 21756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (Size size : availableSizes) { 21786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size); 21796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (availableFpsRanges.length == 0) { 21806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 21816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return true; 21856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } else { 21866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 21876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if depth output is supported, based on the depth capability 21926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 21936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isDepthOutputSupported() { 21946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return isCapabilitySupported( 21956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT); 21966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 21976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 21986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 21996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if standard outputs (PRIVATE, YUV, JPEG) outputs are supported, based on the 22006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * backwards-compatible capability 22016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isColorOutputSupported() { 22036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return isCapabilitySupported( 22046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); 22056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 22086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if optical black regions key is supported. 22096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isOpticalBlackRegionSupported() { 22116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS); 22126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 22156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check if the dynamic black level is supported. 22166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 22186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Note that: This also indicates if the white level is supported, as dynamic black and white 22196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * level must be all supported or none of them is supported. 22206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 22216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public boolean isDynamicBlackLevelSupported() { 22236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return areKeysAvailable(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 22246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 22276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Get the value in index for a fixed-size array from a given key. 22286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>If the camera device is incorrectly reporting values, log a warning and return 22306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * the default value instead.</p> 22316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param key Key to fetch 22336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param defaultValue Default value to return if camera device uses invalid values 22346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param name Human-readable name for the array index (logging only) 22356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param index Array index of the subelement 22366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param size Expected fixed size of the array 22376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The value reported by the camera device, or the defaultValue otherwise. 22396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> T getArrayElementOrDefault(Key<?> key, T defaultValue, String name, int index, 22416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int size) { 22426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim T elementValue = getArrayElementCheckRangeNonNull( 22436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim key, 22446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim index, 22456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim size); 22466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (elementValue == null) { 22486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(key, 22496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim "had no valid " + name + " value; using default of " + defaultValue); 22506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim elementValue = defaultValue; 22516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return elementValue; 22546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 22576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Fetch an array sub-element from an array value given by a key. 22586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 22606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Prints a warning if the sub-element was null. 22616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 22626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p>Use for variable-size arrays since this does not check the array size.</p> 22646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param key Metadata key to look up 22666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param element A non-negative index value. 22676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The array sub-element, or null if the checking failed. 22686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> T getArrayElementNonNull(Key<?> key, int element) { 22706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return getArrayElementCheckRangeNonNull(key, element, IGNORE_SIZE_CHECK); 22716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 22746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Fetch an array sub-element from an array value given by a key. 22756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * <p> 22776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Prints a warning if the array size does not match the size, or if the sub-element was null. 22786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * </p> 22796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 22806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param key Metadata key to look up 22816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param element The index in [0,size) 22826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param size A positive size value or otherwise {@value #IGNORE_SIZE_CHECK} 22836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @return The array sub-element, or null if the checking failed. 22846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 22856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> T getArrayElementCheckRangeNonNull(Key<?> key, int element, int size) { 22866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Object array = getValueFromKeyNonNull(key); 22876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (array == null) { 22896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Warning already printed 22906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return null; 22916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 22926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 22936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (size != IGNORE_SIZE_CHECK) { 22946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim int actualLength = Array.getLength(array); 22956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (actualLength != size) { 22966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(key, 22976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String.format("had the wrong number of elements (%d), expected (%d)", 22986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim actualLength, size)); 22996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return null; 23006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim @SuppressWarnings("unchecked") 23046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim T val = (T) Array.get(array, element); 23056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (val == null) { 23076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(key, "had a null element at index" + element); 23086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return null; 23096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return val; 23126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 23156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Gets the key, logging warnings for null values. 23166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 23176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim public <T> T getValueFromKeyNonNull(Key<T> key) { 23186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (key == null) { 23196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new IllegalArgumentException("key was null"); 23206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim T value = mCharacteristics.get(key); 23236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (value == null) { 23256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(key, "was null"); 23266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return value; 23296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private void checkArrayValuesInRange(Key<int[]> key, int[] array, int min, int max) { 23326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (int value : array) { 23336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max), 23346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value <= max && value >= min); 23356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private void checkArrayValuesInRange(Key<byte[]> key, byte[] array, byte min, byte max) { 23396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (byte value : array) { 23406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max), 23416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim value <= max && value >= min); 23426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /** 23466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Check the uniqueness of the values in a list. 23476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * 23486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param key The key to be checked 23496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * @param list The list contains the value of the key 23506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */ 23516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <U, T> void checkElementDistinct(Key<U> key, List<T> list) { 23526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // Each size must be distinct. 23536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Set<T> sizeSet = new HashSet<T>(list); 23546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim checkTrueForKey(key, "Each size must be distinct", sizeSet.size() == list.size()); 23556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> void checkTrueForKey(Key<T> key, String message, boolean condition) { 23586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (!condition) { 23596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim failKeyCheck(key, message); 23606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim /* Helper function to check if the coupled modes are either all present or all non-present */ 23646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> boolean containsAllOrNone(Collection<T> observedModes, Collection<T> coupledModes) { 23656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (observedModes.containsAll(coupledModes)) { 23666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return true; 23676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim for (T mode : coupledModes) { 23696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim if (observedModes.contains(mode)) { 23706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return false; 23716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim return true; 23746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim 23766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim private <T> void failKeyCheck(Key<T> key, String message) { 23776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // TODO: Consider only warning once per key/message combination if it's too spammy. 23786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim // TODO: Consider offering other options such as throwing an assertion exception 23796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim String failureCause = String.format("The static info key '%s' %s", key.getName(), message); 23806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim switch (mLevel) { 23816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case WARN: 23826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Log.w(TAG, failureCause); 23836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim break; 23846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case COLLECT: 23856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim mCollector.addMessage(failureCause); 23866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim break; 23876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim case ASSERT: 23886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim Assert.fail(failureCause); 23896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim default: 23906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim throw new UnsupportedOperationException("Unhandled level " + mLevel); 23916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim } 23936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim} 2394