• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 #include <camera_metadata_hidden.h>
23 #include <utils/Vector.h>
24 #include <system/graphics.h>
25 #include <media/NdkImage.h>
26 
27 using namespace android;
28 
29 // Formats not listed in the public API, but still available to AImageReader
30 // Enum value must match corresponding enum in ui/PublicFormat.h (which is not
31 // available to VNDK)
32 enum AIMAGE_PRIVATE_FORMATS {
33     /**
34      * Unprocessed implementation-dependent raw
35      * depth measurements, opaque with 16 bit
36      * samples.
37      *
38      */
39 
40     AIMAGE_FORMAT_RAW_DEPTH = 0x1002,
41 
42     /**
43      * Device specific 10 bits depth RAW image format.
44      *
45      * <p>Unprocessed implementation-dependent raw depth measurements, opaque with 10 bit samples
46      * and device specific bit layout.</p>
47      */
48     AIMAGE_FORMAT_RAW_DEPTH10 = 0x1003,
49 };
50 
51 /**
52  * ACameraMetadata Implementation
53  */
ACameraMetadata(camera_metadata_t * buffer,ACAMERA_METADATA_TYPE type)54 ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
55         mData(std::make_shared<CameraMetadata>(buffer)),
56         mType(type) {
57     init();
58 }
59 
ACameraMetadata(const std::shared_ptr<CameraMetadata> & cameraMetadata,ACAMERA_METADATA_TYPE type)60 ACameraMetadata::ACameraMetadata(const std::shared_ptr<CameraMetadata>& cameraMetadata,
61         ACAMERA_METADATA_TYPE type) :
62         mData(cameraMetadata),
63         mType(type) {
64     init();
65 }
66 
ACameraMetadata(const ACameraMetadata & other)67 ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) :
68         mData(std::make_shared<CameraMetadata>(*(other.mData))),
69         mType(other.mType) {
70 }
71 
~ACameraMetadata()72 ACameraMetadata::~ACameraMetadata() {
73 }
74 
75 void
init()76 ACameraMetadata::init() {
77     if (mType == ACM_CHARACTERISTICS) {
78         filterUnsupportedFeatures();
79         filterStreamConfigurations();
80         filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
81         filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
82         filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
83         filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
84         filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
85         filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
86         filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
87         filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
88     }
89     // TODO: filter request/result keys
90     const CameraMetadata& metadata = *mData;
91     const camera_metadata_t *rawMetadata = metadata.getAndLock();
92     metadata_vendor_id_t vendorTagId = get_camera_metadata_vendor_id(rawMetadata);
93     metadata.unlock(rawMetadata);
94     sp<VendorTagDescriptorCache> vtCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
95     if (vtCache == nullptr) {
96         ALOGE("%s: error vendor tag descriptor cache is not initialized", __FUNCTION__);
97         return;
98     }
99     vtCache->getVendorTagDescriptor(vendorTagId, &mVTags);
100     if (mVTags == nullptr) {
101         ALOGE("%s: error retrieving vendor tag descriptor", __FUNCTION__);
102     }
103 }
104 
105 bool
isNdkSupportedCapability(int32_t capability)106 ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
107     switch (capability) {
108         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
109         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
110         case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
111             return false;
112         default:
113             // Assuming every capability passed to this function is actually a
114             // valid capability.
115             return true;
116     }
117 }
118 
119 void
filterUnsupportedFeatures()120 ACameraMetadata::filterUnsupportedFeatures() {
121     // Hide unsupported capabilities (reprocessing)
122     camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
123     if (entry.count == 0 || entry.type != TYPE_BYTE) {
124         ALOGE("%s: malformed available capability key! count %zu, type %d",
125                 __FUNCTION__, entry.count, entry.type);
126         return;
127     }
128 
129     Vector<uint8_t> capabilities;
130     capabilities.setCapacity(entry.count);
131     for (size_t i = 0; i < entry.count; i++) {
132         uint8_t capability = entry.data.u8[i];
133         if (isNdkSupportedCapability(capability)) {
134             capabilities.push(capability);
135 
136             if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
137                 derivePhysicalCameraIds();
138             }
139         }
140     }
141     mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
142 }
143 
144 void
derivePhysicalCameraIds()145 ACameraMetadata::derivePhysicalCameraIds() {
146     ACameraMetadata_const_entry entry;
147     auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
148     if (ret != ACAMERA_OK) {
149         ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
150                 __FUNCTION__, ret);
151         return;
152     }
153 
154     const uint8_t* ids = entry.data.u8;
155     size_t start = 0;
156     for (size_t i = 0; i < entry.count; ++i) {
157         if (ids[i] == '\0') {
158             if (start != i) {
159                 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
160                 mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().c_str());
161             }
162             start = i+1;
163         }
164     }
165 
166     if (mStaticPhysicalCameraIds.size() < 2) {
167         ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
168                 __FUNCTION__, mStaticPhysicalCameraIds.size());
169     }
170 }
171 
172 void
filterDurations(uint32_t tag)173 ACameraMetadata::filterDurations(uint32_t tag) {
174     const int STREAM_CONFIGURATION_SIZE = 4;
175     const int STREAM_FORMAT_OFFSET = 0;
176     const int STREAM_WIDTH_OFFSET = 1;
177     const int STREAM_HEIGHT_OFFSET = 2;
178     const int STREAM_DURATION_OFFSET = 3;
179 
180     camera_metadata_entry entry = mData->find(tag);
181 
182     if (entry.count == 0) {
183         // Duration keys can be missing when corresponding capture feature is not supported
184         return;
185     }
186 
187     if (entry.count % 4 || entry.type != TYPE_INT64) {
188         ALOGE("%s: malformed duration key %d! count %zu, type %d",
189                 __FUNCTION__, tag, entry.count, entry.type);
190         return;
191     }
192 
193     Vector<int64_t> filteredDurations;
194     filteredDurations.setCapacity(entry.count * 2);
195 
196     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
197         int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
198         int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
199         int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
200         int64_t duration = entry.data.i64[i + STREAM_DURATION_OFFSET];
201 
202         // Leave the unfiltered format in so apps depending on previous wrong
203         // filter behavior continue to work
204         filteredDurations.push_back(format);
205         filteredDurations.push_back(width);
206         filteredDurations.push_back(height);
207         filteredDurations.push_back(duration);
208 
209         // Translate HAL formats to NDK format
210         switch (tag) {
211             case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
212             case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
213                 if (format == HAL_PIXEL_FORMAT_BLOB) {
214                     format = AIMAGE_FORMAT_JPEG;
215                     filteredDurations.push_back(format);
216                     filteredDurations.push_back(width);
217                     filteredDurations.push_back(height);
218                     filteredDurations.push_back(duration);
219                 }
220                 break;
221             case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
222             case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
223                 if (format == HAL_PIXEL_FORMAT_BLOB) {
224                     format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
225                     filteredDurations.push_back(format);
226                     filteredDurations.push_back(width);
227                     filteredDurations.push_back(height);
228                     filteredDurations.push_back(duration);
229                 } else if (format == HAL_PIXEL_FORMAT_Y16) {
230                     format = AIMAGE_FORMAT_DEPTH16;
231                     filteredDurations.push_back(format);
232                     filteredDurations.push_back(width);
233                     filteredDurations.push_back(height);
234                     filteredDurations.push_back(duration);
235                 }
236                 break;
237             case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
238             case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
239                 if (format == HAL_PIXEL_FORMAT_BLOB) {
240                     format = AIMAGE_FORMAT_HEIC;
241                     filteredDurations.push_back(format);
242                     filteredDurations.push_back(width);
243                     filteredDurations.push_back(height);
244                     filteredDurations.push_back(duration);
245                 }
246                 break;
247             case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
248             case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
249                 if (format == HAL_PIXEL_FORMAT_BLOB) {
250                     format = AIMAGE_FORMAT_DEPTH_JPEG;
251                     filteredDurations.push_back(format);
252                     filteredDurations.push_back(width);
253                     filteredDurations.push_back(height);
254                     filteredDurations.push_back(duration);
255                 }
256                 break;
257             default:
258                 // Should not reach here
259                 ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
260         }
261     }
262 
263     mData->update(tag, filteredDurations);
264 }
265 
266 void
filterStreamConfigurations()267 ACameraMetadata::filterStreamConfigurations() {
268     const int STREAM_CONFIGURATION_SIZE = 4;
269     const int STREAM_FORMAT_OFFSET = 0;
270     const int STREAM_WIDTH_OFFSET = 1;
271     const int STREAM_HEIGHT_OFFSET = 2;
272     const int STREAM_IS_INPUT_OFFSET = 3;
273     camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
274     if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
275         ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
276                 __FUNCTION__, entry.count, entry.type);
277         return;
278     }
279 
280     Vector<int32_t> filteredStreamConfigs;
281     filteredStreamConfigs.setCapacity(entry.count);
282 
283     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
284         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
285         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
286         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
287         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
288         if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
289             // Hide input streams
290             continue;
291         }
292         // Translate HAL formats to NDK format
293         if (format == HAL_PIXEL_FORMAT_BLOB) {
294             format = AIMAGE_FORMAT_JPEG;
295         }
296         filteredStreamConfigs.push_back(format);
297         filteredStreamConfigs.push_back(width);
298         filteredStreamConfigs.push_back(height);
299         filteredStreamConfigs.push_back(isInput);
300     }
301 
302     if (filteredStreamConfigs.size() > 0) {
303         mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
304     }
305 
306     entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
307     if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
308         ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
309                 __FUNCTION__, entry.count, entry.type);
310         return;
311     }
312 
313     Vector<int32_t> filteredDepthStreamConfigs;
314     filteredDepthStreamConfigs.setCapacity(entry.count);
315 
316     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
317         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
318         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
319         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
320         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
321         if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
322             // Hide input streams
323             continue;
324         }
325         // Translate HAL formats to NDK format
326         if (format == HAL_PIXEL_FORMAT_BLOB) {
327             format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
328         } else if (format == HAL_PIXEL_FORMAT_Y16) {
329             format = AIMAGE_FORMAT_DEPTH16;
330         } else if (format == HAL_PIXEL_FORMAT_RAW16) {
331             format = static_cast<int32_t>(AIMAGE_FORMAT_RAW_DEPTH);
332         } else if (format == HAL_PIXEL_FORMAT_RAW10) {
333             format = static_cast<int32_t>(AIMAGE_FORMAT_RAW_DEPTH10);
334         }
335 
336         filteredDepthStreamConfigs.push_back(format);
337         filteredDepthStreamConfigs.push_back(width);
338         filteredDepthStreamConfigs.push_back(height);
339         filteredDepthStreamConfigs.push_back(isInput);
340     }
341 
342     if (filteredDepthStreamConfigs.size() > 0) {
343         mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
344                 filteredDepthStreamConfigs);
345     }
346 
347     entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
348     Vector<int32_t> filteredHeicStreamConfigs;
349     filteredHeicStreamConfigs.setCapacity(entry.count);
350 
351     for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
352         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
353         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
354         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
355         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
356         if (isInput == ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT) {
357             // Hide input streams
358             continue;
359         }
360         // Translate HAL formats to NDK format
361         if (format == HAL_PIXEL_FORMAT_BLOB) {
362             format = AIMAGE_FORMAT_HEIC;
363         }
364 
365         filteredHeicStreamConfigs.push_back(format);
366         filteredHeicStreamConfigs.push_back(width);
367         filteredHeicStreamConfigs.push_back(height);
368         filteredHeicStreamConfigs.push_back(isInput);
369     }
370     mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
371 
372     entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
373     Vector<int32_t> filteredDynamicDepthStreamConfigs;
374     filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
375 
376     for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
377         int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
378         int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
379         int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
380         int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
381         if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
382             // Hide input streams
383             continue;
384         }
385         // Translate HAL formats to NDK format
386         if (format == HAL_PIXEL_FORMAT_BLOB) {
387             format = AIMAGE_FORMAT_DEPTH_JPEG;
388         }
389 
390         filteredDynamicDepthStreamConfigs.push_back(format);
391         filteredDynamicDepthStreamConfigs.push_back(width);
392         filteredDynamicDepthStreamConfigs.push_back(height);
393         filteredDynamicDepthStreamConfigs.push_back(isInput);
394     }
395     mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
396             filteredDynamicDepthStreamConfigs);
397 }
398 
399 bool
isVendorTag(const uint32_t tag)400 ACameraMetadata::isVendorTag(const uint32_t tag) {
401     uint32_t tag_section = tag >> 16;
402     if (tag_section >= VENDOR_SECTION) {
403         return true;
404     }
405     return false;
406 }
407 
408 camera_status_t
getConstEntry(uint32_t tag,ACameraMetadata_const_entry * entry) const409 ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
410     if (entry == nullptr) {
411         return ACAMERA_ERROR_INVALID_PARAMETER;
412     }
413 
414     Mutex::Autolock _l(mLock);
415 
416     camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData.get())->find(tag);
417     if (rawEntry.count == 0) {
418         return ACAMERA_ERROR_METADATA_NOT_FOUND;
419     }
420     entry->tag = tag;
421     entry->type = rawEntry.type;
422     entry->count = rawEntry.count;
423     entry->data.u8 = rawEntry.data.u8;
424     return ACAMERA_OK;
425 }
426 
427 camera_status_t
update(uint32_t tag,uint32_t count,const uint8_t * data)428 ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
429     return updateImpl<uint8_t>(tag, count, data);
430 }
431 
432 camera_status_t
update(uint32_t tag,uint32_t count,const int32_t * data)433 ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
434     return updateImpl<int32_t>(tag, count, data);
435 }
436 
437 camera_status_t
update(uint32_t tag,uint32_t count,const float * data)438 ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
439     return updateImpl<float>(tag, count, data);
440 }
441 
442 camera_status_t
update(uint32_t tag,uint32_t count,const double * data)443 ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
444     return updateImpl<double>(tag, count, data);
445 }
446 
447 camera_status_t
update(uint32_t tag,uint32_t count,const int64_t * data)448 ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
449     return updateImpl<int64_t>(tag, count, data);
450 }
451 
452 camera_status_t
update(uint32_t tag,uint32_t count,const ACameraMetadata_rational * data)453 ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
454     return updateImpl<camera_metadata_rational_t>(tag, count, data);
455 }
456 
457 camera_status_t
getTags(int32_t * numTags,const uint32_t ** tags) const458 ACameraMetadata::getTags(/*out*/int32_t* numTags,
459                          /*out*/const uint32_t** tags) const {
460     Mutex::Autolock _l(mLock);
461     if (mTags.size() == 0) {
462         size_t entry_count = mData->entryCount();
463         mTags.setCapacity(entry_count);
464         const camera_metadata_t* rawMetadata = mData->getAndLock();
465         for (size_t i = 0; i < entry_count; i++) {
466             camera_metadata_ro_entry_t entry;
467             int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
468             if (ret != 0) {
469                 mData->unlock(rawMetadata);
470                 ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
471                 return ACAMERA_ERROR_UNKNOWN;
472             }
473             // Hide system key from users
474             if (sSystemTags.count(entry.tag) == 0) {
475                 mTags.push_back(entry.tag);
476             }
477         }
478         mData->unlock(rawMetadata);
479     }
480 
481     *numTags = mTags.size();
482     *tags = mTags.array();
483     return ACAMERA_OK;
484 }
485 
486 const CameraMetadata&
getInternalData() const487 ACameraMetadata::getInternalData() const {
488     return (*mData);
489 }
490 
491 camera_status_t
getTagFromName(const char * name,uint32_t * tag) const492 ACameraMetadata::getTagFromName(const char *name, uint32_t *tag) const {
493     Mutex::Autolock _l(mLock);
494     status_t status = CameraMetadata::getTagFromName(name, mVTags.get(), tag);
495     return status == OK ? ACAMERA_OK : ACAMERA_ERROR_METADATA_NOT_FOUND;
496 }
497 
498 bool
isLogicalMultiCamera(size_t * count,const char * const ** physicalCameraIds) const499 ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
500     if (mType != ACM_CHARACTERISTICS) {
501         ALOGE("%s must be called for a static metadata!", __FUNCTION__);
502         return false;
503     }
504     if (count == nullptr || physicalCameraIds == nullptr) {
505         ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
506                 count, physicalCameraIds);
507         return false;
508     }
509 
510     if (mStaticPhysicalCameraIds.size() >= 2) {
511         *count = mStaticPhysicalCameraIds.size();
512         *physicalCameraIds = mStaticPhysicalCameraIds.data();
513         return true;
514     }
515 
516     return false;
517 }
518 
519 // TODO: some of key below should be hidden from user
520 // ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
521 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
522  * The key entries below this point are generated from metadata
523  * definitions in /system/media/camera/docs. Do not modify by hand or
524  * modify the comment blocks at the start or end.
525  *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
526 
527 bool
isCaptureRequestTag(const uint32_t tag)528 ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
529     // Skip check for vendor keys
530     if (isVendorTag(tag)) {
531         return true;
532     }
533 
534     switch (tag) {
535         case ACAMERA_COLOR_CORRECTION_MODE:
536         case ACAMERA_COLOR_CORRECTION_TRANSFORM:
537         case ACAMERA_COLOR_CORRECTION_GAINS:
538         case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
539         case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
540         case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
541         case ACAMERA_CONTROL_AE_LOCK:
542         case ACAMERA_CONTROL_AE_MODE:
543         case ACAMERA_CONTROL_AE_REGIONS:
544         case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
545         case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
546         case ACAMERA_CONTROL_AF_MODE:
547         case ACAMERA_CONTROL_AF_REGIONS:
548         case ACAMERA_CONTROL_AF_TRIGGER:
549         case ACAMERA_CONTROL_AWB_LOCK:
550         case ACAMERA_CONTROL_AWB_MODE:
551         case ACAMERA_CONTROL_AWB_REGIONS:
552         case ACAMERA_CONTROL_CAPTURE_INTENT:
553         case ACAMERA_CONTROL_EFFECT_MODE:
554         case ACAMERA_CONTROL_MODE:
555         case ACAMERA_CONTROL_SCENE_MODE:
556         case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
557         case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
558         case ACAMERA_CONTROL_ENABLE_ZSL:
559         case ACAMERA_CONTROL_EXTENDED_SCENE_MODE:
560         case ACAMERA_CONTROL_ZOOM_RATIO:
561         case ACAMERA_CONTROL_SETTINGS_OVERRIDE:
562         case ACAMERA_CONTROL_AUTOFRAMING:
563         case ACAMERA_EDGE_MODE:
564         case ACAMERA_FLASH_MODE:
565         case ACAMERA_FLASH_STRENGTH_LEVEL:
566         case ACAMERA_HOT_PIXEL_MODE:
567         case ACAMERA_JPEG_GPS_COORDINATES:
568         case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
569         case ACAMERA_JPEG_GPS_TIMESTAMP:
570         case ACAMERA_JPEG_ORIENTATION:
571         case ACAMERA_JPEG_QUALITY:
572         case ACAMERA_JPEG_THUMBNAIL_QUALITY:
573         case ACAMERA_JPEG_THUMBNAIL_SIZE:
574         case ACAMERA_LENS_APERTURE:
575         case ACAMERA_LENS_FILTER_DENSITY:
576         case ACAMERA_LENS_FOCAL_LENGTH:
577         case ACAMERA_LENS_FOCUS_DISTANCE:
578         case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
579         case ACAMERA_NOISE_REDUCTION_MODE:
580         case ACAMERA_SCALER_CROP_REGION:
581         case ACAMERA_SCALER_ROTATE_AND_CROP:
582         case ACAMERA_SENSOR_EXPOSURE_TIME:
583         case ACAMERA_SENSOR_FRAME_DURATION:
584         case ACAMERA_SENSOR_SENSITIVITY:
585         case ACAMERA_SENSOR_TEST_PATTERN_DATA:
586         case ACAMERA_SENSOR_TEST_PATTERN_MODE:
587         case ACAMERA_SENSOR_PIXEL_MODE:
588         case ACAMERA_SHADING_MODE:
589         case ACAMERA_STATISTICS_FACE_DETECT_MODE:
590         case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
591         case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
592         case ACAMERA_STATISTICS_OIS_DATA_MODE:
593         case ACAMERA_TONEMAP_CURVE_BLUE:
594         case ACAMERA_TONEMAP_CURVE_GREEN:
595         case ACAMERA_TONEMAP_CURVE_RED:
596         case ACAMERA_TONEMAP_MODE:
597         case ACAMERA_TONEMAP_GAMMA:
598         case ACAMERA_TONEMAP_PRESET_CURVE:
599         case ACAMERA_BLACK_LEVEL_LOCK:
600         case ACAMERA_DISTORTION_CORRECTION_MODE:
601             return true;
602         default:
603             return false;
604     }
605 }
606 
607 // System tags that should be hidden from users
608 std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
609     ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
610     ANDROID_CONTROL_AE_PRECAPTURE_ID,
611     ANDROID_CONTROL_AF_TRIGGER_ID,
612     ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
613     ANDROID_DEMOSAIC_MODE,
614     ANDROID_EDGE_STRENGTH,
615     ANDROID_FLASH_FIRING_POWER,
616     ANDROID_FLASH_FIRING_TIME,
617     ANDROID_FLASH_COLOR_TEMPERATURE,
618     ANDROID_FLASH_MAX_ENERGY,
619     ANDROID_FLASH_INFO_CHARGE_DURATION,
620     ANDROID_JPEG_MAX_SIZE,
621     ANDROID_JPEG_SIZE,
622     ANDROID_NOISE_REDUCTION_STRENGTH,
623     ANDROID_QUIRKS_METERING_CROP_REGION,
624     ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
625     ANDROID_QUIRKS_USE_ZSL_FORMAT,
626     ANDROID_REQUEST_INPUT_STREAMS,
627     ANDROID_REQUEST_METADATA_MODE,
628     ANDROID_REQUEST_OUTPUT_STREAMS,
629     ANDROID_REQUEST_TYPE,
630     ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
631     ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
632     ANDROID_SCALER_AVAILABLE_RAW_SIZES,
633     ANDROID_SENSOR_BASE_GAIN_FACTOR,
634     ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
635     ANDROID_SENSOR_TEMPERATURE,
636     ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
637     ANDROID_SENSOR_PROFILE_TONE_CURVE,
638     ANDROID_SENSOR_OPAQUE_RAW_SIZE,
639     ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
640     ANDROID_SHADING_STRENGTH,
641     ANDROID_STATISTICS_HISTOGRAM_MODE,
642     ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
643     ANDROID_STATISTICS_HISTOGRAM,
644     ANDROID_STATISTICS_SHARPNESS_MAP,
645     ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
646     ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
647     ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
648     ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
649     ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
650     ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
651     ANDROID_HEIC_INFO_SUPPORTED,
652     ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
653 });
654 
655 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
656  * End generated code
657  *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
658