Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "ACameraMetadata"
     19 
     20 #include "ACameraMetadata.h"
     21 #include <utils/Vector.h>
     22 #include <system/graphics.h>
     23 #include <media/NdkImage.h>
     24 
     25 using namespace android;
     26 
     27 /**
     28  * ACameraMetadata Implementation
     29  */
     30 ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
     31         mData(buffer), mType(type) {
     32     if (mType == ACM_CHARACTERISTICS) {
     33         filterUnsupportedFeatures();
     34         filterStreamConfigurations();
     35         filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
     36         filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
     37         filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
     38         filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
     39         filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
     40         filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
     41         filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
     42         filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
     43     }
     44     // TODO: filter request/result keys
     45 }
     46 
     47 bool
     48 ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
     49     switch (capability) {
     50         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
     51         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
     52         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
     53             return false;
     54         default:
     55             // Assuming every capability passed to this function is actually a
     56             // valid capability.
     57             return true;
     58     }
     59 }
     60 
     61 void
     62 ACameraMetadata::filterUnsupportedFeatures() {
     63     // Hide unsupported capabilities (reprocessing)
     64     camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
     65     if (entry.count == 0 || entry.type != TYPE_BYTE) {
     66         ALOGE("%s: malformed available capability key! count %zu, type %d",
     67                 __FUNCTION__, entry.count, entry.type);
     68         return;
     69     }
     70 
     71     Vector<uint8_t> capabilities;
     72     capabilities.setCapacity(entry.count);
     73     for (size_t i = 0; i < entry.count; i++) {
     74         uint8_t capability = entry.data.u8[i];
     75         if (isNdkSupportedCapability(capability)) {
     76             capabilities.push(capability);
     77 
     78             if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
     79                 derivePhysicalCameraIds();
     80             }
     81         }
     82     }
     83     mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
     84 }
     85 
     86 void
     87 ACameraMetadata::derivePhysicalCameraIds() {
     88     ACameraMetadata_const_entry entry;
     89     auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
     90     if (ret != ACAMERA_OK) {
     91         ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
     92                 __FUNCTION__, ret);
     93         return;
     94     }
     95 
     96     const uint8_t* ids = entry.data.u8;
     97     size_t start = 0;
     98     for (size_t i = 0; i < entry.count; ++i) {
     99         if (ids[i] == '\0') {
    100             if (start != i) {
    101                 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
    102                 mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().string());
    103             }
    104             start = i+1;
    105         }
    106     }
    107 
    108     if (mStaticPhysicalCameraIds.size() < 2) {
    109         ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
    110                 __FUNCTION__, mStaticPhysicalCameraIds.size());
    111     }
    112 }
    113 
    114 void
    115 ACameraMetadata::filterDurations(uint32_t tag) {
    116     const int STREAM_CONFIGURATION_SIZE = 4;
    117     const int STREAM_FORMAT_OFFSET = 0;
    118     const int STREAM_WIDTH_OFFSET = 1;
    119     const int STREAM_HEIGHT_OFFSET = 2;
    120     const int STREAM_DURATION_OFFSET = 3;
    121     camera_metadata_entry entry = mData.find(tag);
    122     if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
    123         ALOGE("%s: malformed duration key %d! count %zu, type %d",
    124                 __FUNCTION__, tag, entry.count, entry.type);
    125         return;
    126     }
    127     Vector<int64_t> filteredDurations;
    128     filteredDurations.setCapacity(entry.count * 2);
    129 
    130     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
    131         int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
    132         int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
    133         int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
    134         int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
    135 
    136         // Leave the unfiltered format in so apps depending on previous wrong
    137         // filter behavior continue to work
    138         filteredDurations.push_back(format);
    139         filteredDurations.push_back(width);
    140         filteredDurations.push_back(height);
    141         filteredDurations.push_back(duration);
    142 
    143         // Translate HAL formats to NDK format
    144         switch (tag) {
    145             case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
    146             case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
    147                 if (format == HAL_PIXEL_FORMAT_BLOB) {
    148                     format = AIMAGE_FORMAT_JPEG;
    149                     filteredDurations.push_back(format);
    150                     filteredDurations.push_back(width);
    151                     filteredDurations.push_back(height);
    152                     filteredDurations.push_back(duration);
    153                 }
    154                 break;
    155             case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
    156             case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
    157                 if (format == HAL_PIXEL_FORMAT_BLOB) {
    158                     format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
    159                     filteredDurations.push_back(format);
    160                     filteredDurations.push_back(width);
    161                     filteredDurations.push_back(height);
    162                     filteredDurations.push_back(duration);
    163                 } else if (format == HAL_PIXEL_FORMAT_Y16) {
    164                     format = AIMAGE_FORMAT_DEPTH16;
    165                     filteredDurations.push_back(format);
    166                     filteredDurations.push_back(width);
    167                     filteredDurations.push_back(height);
    168                     filteredDurations.push_back(duration);
    169                 }
    170                 break;
    171             case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
    172             case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
    173                 if (format == HAL_PIXEL_FORMAT_BLOB) {
    174                     format = AIMAGE_FORMAT_HEIC;
    175                     filteredDurations.push_back(format);
    176                     filteredDurations.push_back(width);
    177                     filteredDurations.push_back(height);
    178                     filteredDurations.push_back(duration);
    179                 }
    180                 break;
    181             case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
    182             case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
    183                 if (format == HAL_PIXEL_FORMAT_BLOB) {
    184                     format = AIMAGE_FORMAT_DEPTH_JPEG;
    185                     filteredDurations.push_back(format);
    186                     filteredDurations.push_back(width);
    187                     filteredDurations.push_back(height);
    188                     filteredDurations.push_back(duration);
    189                 }
    190                 break;
    191             default:
    192                 // Should not reach here
    193                 ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
    194         }
    195     }
    196 
    197     mData.update(tag, filteredDurations);
    198 }
    199 
    200 void
    201 ACameraMetadata::filterStreamConfigurations() {
    202     const int STREAM_CONFIGURATION_SIZE = 4;
    203     const int STREAM_FORMAT_OFFSET = 0;
    204     const int STREAM_WIDTH_OFFSET = 1;
    205     const int STREAM_HEIGHT_OFFSET = 2;
    206     const int STREAM_IS_INPUT_OFFSET = 3;
    207     camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
    208     if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
    209         ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
    210                 __FUNCTION__, entry.count, entry.type);
    211         return;
    212     }
    213 
    214     Vector<int32_t> filteredStreamConfigs;
    215     filteredStreamConfigs.setCapacity(entry.count);
    216 
    217     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
    218         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
    219         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
    220         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
    221         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
    222         if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
    223             // Hide input streams
    224             continue;
    225         }
    226         // Translate HAL formats to NDK format
    227         if (format == HAL_PIXEL_FORMAT_BLOB) {
    228             format = AIMAGE_FORMAT_JPEG;
    229         }
    230         filteredStreamConfigs.push_back(format);
    231         filteredStreamConfigs.push_back(width);
    232         filteredStreamConfigs.push_back(height);
    233         filteredStreamConfigs.push_back(isInput);
    234     }
    235 
    236     if (filteredStreamConfigs.size() > 0) {
    237         mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
    238     }
    239 
    240     entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
    241     if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
    242         ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
    243                 __FUNCTION__, entry.count, entry.type);
    244         return;
    245     }
    246 
    247     Vector<int32_t> filteredDepthStreamConfigs;
    248     filteredDepthStreamConfigs.setCapacity(entry.count);
    249 
    250     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
    251         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
    252         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
    253         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
    254         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
    255         if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
    256             // Hide input streams
    257             continue;
    258         }
    259         // Translate HAL formats to NDK format
    260         if (format == HAL_PIXEL_FORMAT_BLOB) {
    261             format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
    262         } else if (format == HAL_PIXEL_FORMAT_Y16) {
    263             format = AIMAGE_FORMAT_DEPTH16;
    264         }
    265 
    266         filteredDepthStreamConfigs.push_back(format);
    267         filteredDepthStreamConfigs.push_back(width);
    268         filteredDepthStreamConfigs.push_back(height);
    269         filteredDepthStreamConfigs.push_back(isInput);
    270     }
    271 
    272     if (filteredDepthStreamConfigs.size() > 0) {
    273         mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
    274                 filteredDepthStreamConfigs);
    275     }
    276 
    277     entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
    278     Vector<int32_t> filteredHeicStreamConfigs;
    279     filteredHeicStreamConfigs.setCapacity(entry.count);
    280 
    281     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
    282         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
    283         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
    284         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
    285         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
    286         if (isInput == ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT) {
    287             // Hide input streams
    288             continue;
    289         }
    290         // Translate HAL formats to NDK format
    291         if (format == HAL_PIXEL_FORMAT_BLOB) {
    292             format = AIMAGE_FORMAT_HEIC;
    293         }
    294 
    295         filteredHeicStreamConfigs.push_back(format);
    296         filteredHeicStreamConfigs.push_back(width);
    297         filteredHeicStreamConfigs.push_back(height);
    298         filteredHeicStreamConfigs.push_back(isInput);
    299     }
    300     mData.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
    301 
    302     entry = mData.find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
    303     Vector<int32_t> filteredDynamicDepthStreamConfigs;
    304     filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
    305 
    306     for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
    307         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
    308         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
    309         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
    310         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
    311         if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
    312             // Hide input streams
    313             continue;
    314         }
    315         // Translate HAL formats to NDK format
    316         if (format == HAL_PIXEL_FORMAT_BLOB) {
    317             format = AIMAGE_FORMAT_DEPTH_JPEG;
    318         }
    319 
    320         filteredDynamicDepthStreamConfigs.push_back(format);
    321         filteredDynamicDepthStreamConfigs.push_back(width);
    322         filteredDynamicDepthStreamConfigs.push_back(height);
    323         filteredDynamicDepthStreamConfigs.push_back(isInput);
    324     }
    325     mData.update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
    326             filteredDynamicDepthStreamConfigs);
    327 }
    328 
    329 bool
    330 ACameraMetadata::isVendorTag(const uint32_t tag) {
    331     uint32_t tag_section = tag >> 16;
    332     if (tag_section >= VENDOR_SECTION) {
    333         return true;
    334     }
    335     return false;
    336 }
    337 
    338 camera_status_t
    339 ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
    340     if (entry == nullptr) {
    341         return ACAMERA_ERROR_INVALID_PARAMETER;
    342     }
    343 
    344     Mutex::Autolock _l(mLock);
    345 
    346     camera_metadata_ro_entry rawEntry = mData.find(tag);
    347     if (rawEntry.count == 0) {
    348         ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
    349         return ACAMERA_ERROR_METADATA_NOT_FOUND;
    350     }
    351     entry->tag = tag;
    352     entry->type = rawEntry.type;
    353     entry->count = rawEntry.count;
    354     entry->data.u8 = rawEntry.data.u8;
    355     return ACAMERA_OK;
    356 }
    357 
    358 camera_status_t
    359 ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
    360     return updateImpl<uint8_t>(tag, count, data);
    361 }
    362 
    363 camera_status_t
    364 ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
    365     return updateImpl<int32_t>(tag, count, data);
    366 }
    367 
    368 camera_status_t
    369 ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
    370     return updateImpl<float>(tag, count, data);
    371 }
    372 
    373 camera_status_t
    374 ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
    375     return updateImpl<double>(tag, count, data);
    376 }
    377 
    378 camera_status_t
    379 ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
    380     return updateImpl<int64_t>(tag, count, data);
    381 }
    382 
    383 camera_status_t
    384 ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
    385     return updateImpl<camera_metadata_rational_t>(tag, count, data);
    386 }
    387 
    388 camera_status_t
    389 ACameraMetadata::getTags(/*out*/int32_t* numTags,
    390                          /*out*/const uint32_t** tags) const {
    391     Mutex::Autolock _l(mLock);
    392     if (mTags.size() == 0) {
    393         size_t entry_count = mData.entryCount();
    394         mTags.setCapacity(entry_count);
    395         const camera_metadata_t* rawMetadata = mData.getAndLock();
    396         for (size_t i = 0; i < entry_count; i++) {
    397             camera_metadata_ro_entry_t entry;
    398             int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
    399             if (ret != 0) {
    400                 ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
    401                 return ACAMERA_ERROR_UNKNOWN;
    402             }
    403             // Hide system key from users
    404             if (sSystemTags.count(entry.tag) == 0) {
    405                 mTags.push_back(entry.tag);
    406             }
    407         }
    408         mData.unlock(rawMetadata);
    409     }
    410 
    411     *numTags = mTags.size();
    412     *tags = mTags.array();
    413     return ACAMERA_OK;
    414 }
    415 
    416 const CameraMetadata&
    417 ACameraMetadata::getInternalData() const {
    418     return mData;
    419 }
    420 
    421 bool
    422 ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
    423     if (mType != ACM_CHARACTERISTICS) {
    424         ALOGE("%s must be called for a static metadata!", __FUNCTION__);
    425         return false;
    426     }
    427     if (count == nullptr || physicalCameraIds == nullptr) {
    428         ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
    429                 count, physicalCameraIds);
    430         return false;
    431     }
    432 
    433     if (mStaticPhysicalCameraIds.size() >= 2) {
    434         *count = mStaticPhysicalCameraIds.size();
    435         *physicalCameraIds = mStaticPhysicalCameraIds.data();
    436         return true;
    437     }
    438 
    439     return false;
    440 }
    441 
    442 // TODO: some of key below should be hidden from user
    443 // ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
    444 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
    445  * The key entries below this point are generated from metadata
    446  * definitions in /system/media/camera/docs. Do not modify by hand or
    447  * modify the comment blocks at the start or end.
    448  *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
    449 
    450 bool
    451 ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
    452     // Skip check for vendor keys
    453     if (isVendorTag(tag)) {
    454         return true;
    455     }
    456 
    457     switch (tag) {
    458         case ACAMERA_COLOR_CORRECTION_MODE:
    459         case ACAMERA_COLOR_CORRECTION_TRANSFORM:
    460         case ACAMERA_COLOR_CORRECTION_GAINS:
    461         case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
    462         case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
    463         case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
    464         case ACAMERA_CONTROL_AE_LOCK:
    465         case ACAMERA_CONTROL_AE_MODE:
    466         case ACAMERA_CONTROL_AE_REGIONS:
    467         case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
    468         case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
    469         case ACAMERA_CONTROL_AF_MODE:
    470         case ACAMERA_CONTROL_AF_REGIONS:
    471         case ACAMERA_CONTROL_AF_TRIGGER:
    472         case ACAMERA_CONTROL_AWB_LOCK:
    473         case ACAMERA_CONTROL_AWB_MODE:
    474         case ACAMERA_CONTROL_AWB_REGIONS:
    475         case ACAMERA_CONTROL_CAPTURE_INTENT:
    476         case ACAMERA_CONTROL_EFFECT_MODE:
    477         case ACAMERA_CONTROL_MODE:
    478         case ACAMERA_CONTROL_SCENE_MODE:
    479         case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
    480         case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
    481         case ACAMERA_CONTROL_ENABLE_ZSL:
    482         case ACAMERA_EDGE_MODE:
    483         case ACAMERA_FLASH_MODE:
    484         case ACAMERA_HOT_PIXEL_MODE:
    485         case ACAMERA_JPEG_GPS_COORDINATES:
    486         case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
    487         case ACAMERA_JPEG_GPS_TIMESTAMP:
    488         case ACAMERA_JPEG_ORIENTATION:
    489         case ACAMERA_JPEG_QUALITY:
    490         case ACAMERA_JPEG_THUMBNAIL_QUALITY:
    491         case ACAMERA_JPEG_THUMBNAIL_SIZE:
    492         case ACAMERA_LENS_APERTURE:
    493         case ACAMERA_LENS_FILTER_DENSITY:
    494         case ACAMERA_LENS_FOCAL_LENGTH:
    495         case ACAMERA_LENS_FOCUS_DISTANCE:
    496         case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
    497         case ACAMERA_NOISE_REDUCTION_MODE:
    498         case ACAMERA_SCALER_CROP_REGION:
    499         case ACAMERA_SENSOR_EXPOSURE_TIME:
    500         case ACAMERA_SENSOR_FRAME_DURATION:
    501         case ACAMERA_SENSOR_SENSITIVITY:
    502         case ACAMERA_SENSOR_TEST_PATTERN_DATA:
    503         case ACAMERA_SENSOR_TEST_PATTERN_MODE:
    504         case ACAMERA_SHADING_MODE:
    505         case ACAMERA_STATISTICS_FACE_DETECT_MODE:
    506         case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
    507         case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
    508         case ACAMERA_STATISTICS_OIS_DATA_MODE:
    509         case ACAMERA_TONEMAP_CURVE_BLUE:
    510         case ACAMERA_TONEMAP_CURVE_GREEN:
    511         case ACAMERA_TONEMAP_CURVE_RED:
    512         case ACAMERA_TONEMAP_MODE:
    513         case ACAMERA_TONEMAP_GAMMA:
    514         case ACAMERA_TONEMAP_PRESET_CURVE:
    515         case ACAMERA_BLACK_LEVEL_LOCK:
    516         case ACAMERA_DISTORTION_CORRECTION_MODE:
    517             return true;
    518         default:
    519             return false;
    520     }
    521 }
    522 
    523 // System tags that should be hidden from users
    524 std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
    525     ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
    526     ANDROID_CONTROL_AE_PRECAPTURE_ID,
    527     ANDROID_CONTROL_AF_TRIGGER_ID,
    528     ANDROID_DEMOSAIC_MODE,
    529     ANDROID_EDGE_STRENGTH,
    530     ANDROID_FLASH_FIRING_POWER,
    531     ANDROID_FLASH_FIRING_TIME,
    532     ANDROID_FLASH_COLOR_TEMPERATURE,
    533     ANDROID_FLASH_MAX_ENERGY,
    534     ANDROID_FLASH_INFO_CHARGE_DURATION,
    535     ANDROID_JPEG_MAX_SIZE,
    536     ANDROID_JPEG_SIZE,
    537     ANDROID_NOISE_REDUCTION_STRENGTH,
    538     ANDROID_QUIRKS_METERING_CROP_REGION,
    539     ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
    540     ANDROID_QUIRKS_USE_ZSL_FORMAT,
    541     ANDROID_REQUEST_INPUT_STREAMS,
    542     ANDROID_REQUEST_METADATA_MODE,
    543     ANDROID_REQUEST_OUTPUT_STREAMS,
    544     ANDROID_REQUEST_TYPE,
    545     ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
    546     ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
    547     ANDROID_SCALER_AVAILABLE_RAW_SIZES,
    548     ANDROID_SENSOR_BASE_GAIN_FACTOR,
    549     ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
    550     ANDROID_SENSOR_TEMPERATURE,
    551     ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
    552     ANDROID_SENSOR_PROFILE_TONE_CURVE,
    553     ANDROID_SENSOR_OPAQUE_RAW_SIZE,
    554     ANDROID_SHADING_STRENGTH,
    555     ANDROID_STATISTICS_HISTOGRAM_MODE,
    556     ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
    557     ANDROID_STATISTICS_HISTOGRAM,
    558     ANDROID_STATISTICS_SHARPNESS_MAP,
    559     ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
    560     ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
    561     ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
    562     ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
    563     ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
    564     ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
    565     ANDROID_HEIC_INFO_SUPPORTED,
    566     ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
    567 });
    568 
    569 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
    570  * End generated code
    571  *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
    572