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  */
ACameraMetadata(camera_metadata_t * buffer,ACAMERA_METADATA_TYPE type)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
isNdkSupportedCapability(int32_t capability)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
filterUnsupportedFeatures()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
derivePhysicalCameraIds()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
filterDurations(uint32_t tag)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
filterStreamConfigurations()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
isVendorTag(const uint32_t tag)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
getConstEntry(uint32_t tag,ACameraMetadata_const_entry * entry) const339 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
update(uint32_t tag,uint32_t count,const uint8_t * data)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
update(uint32_t tag,uint32_t count,const int32_t * data)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
update(uint32_t tag,uint32_t count,const float * data)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
update(uint32_t tag,uint32_t count,const double * data)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
update(uint32_t tag,uint32_t count,const int64_t * data)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
update(uint32_t tag,uint32_t count,const ACameraMetadata_rational * data)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
getTags(int32_t * numTags,const uint32_t ** tags) const389 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&
getInternalData() const417 ACameraMetadata::getInternalData() const {
418     return mData;
419 }
420 
421 bool
isLogicalMultiCamera(size_t * count,const char * const ** physicalCameraIds) const422 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
isCaptureRequestTag(const uint32_t tag)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