1 /*
2 * Copyright (C) 2016 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_TAG "CamComm1.0-VTDesc"
18
19 #include <camera_metadata_hidden.h>
20 #include <log/log.h>
21 #include <system/camera_metadata.h>
22 #include <utils/Errors.h>
23 #include <utils/Mutex.h>
24 #include <utils/SortedVector.h>
25 #include <utils/Vector.h>
26
27 #include "VendorTagDescriptor.h"
28
29 #include <stdio.h>
30 #include <string.h>
31
32 namespace android {
33 namespace hardware {
34 namespace camera2 {
35 namespace params {
36
~VendorTagDescriptor()37 VendorTagDescriptor::~VendorTagDescriptor() {
38 size_t len = mReverseMapping.size();
39 for (size_t i = 0; i < len; ++i) {
40 delete mReverseMapping[i];
41 }
42 }
43
VendorTagDescriptor()44 VendorTagDescriptor::VendorTagDescriptor() : mTagCount(0), mVendorOps() {}
45
VendorTagDescriptor(const VendorTagDescriptor & src)46 VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
47 copyFrom(src);
48 }
49
operator =(const VendorTagDescriptor & rhs)50 VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
51 copyFrom(rhs);
52 return *this;
53 }
54
copyFrom(const VendorTagDescriptor & src)55 void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
56 if (this == &src) return;
57
58 size_t len = mReverseMapping.size();
59 for (size_t i = 0; i < len; ++i) {
60 delete mReverseMapping[i];
61 }
62 mReverseMapping.clear();
63
64 len = src.mReverseMapping.size();
65 // Have to copy KeyedVectors inside mReverseMapping
66 for (size_t i = 0; i < len; ++i) {
67 KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
68 *nameMapper = *(src.mReverseMapping.valueAt(i));
69 mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
70 }
71 // Everything else is simple
72 mTagToNameMap = src.mTagToNameMap;
73 mTagToSectionMap = src.mTagToSectionMap;
74 mTagToTypeMap = src.mTagToTypeMap;
75 mSections = src.mSections;
76 mTagCount = src.mTagCount;
77 mVendorOps = src.mVendorOps;
78 }
79
getTagCount() const80 int VendorTagDescriptor::getTagCount() const {
81 size_t size = mTagToNameMap.size();
82 if (size == 0) {
83 return VENDOR_TAG_COUNT_ERR;
84 }
85 return size;
86 }
87
getTagArray(uint32_t * tagArray) const88 void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
89 size_t size = mTagToNameMap.size();
90 for (size_t i = 0; i < size; ++i) {
91 tagArray[i] = mTagToNameMap.keyAt(i);
92 }
93 }
94
getSectionName(uint32_t tag) const95 const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
96 ssize_t index = mTagToSectionMap.indexOfKey(tag);
97 if (index < 0) {
98 return VENDOR_SECTION_NAME_ERR;
99 }
100 return mSections[mTagToSectionMap.valueAt(index)].c_str();
101 }
102
getSectionIndex(uint32_t tag) const103 ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
104 return mTagToSectionMap.valueFor(tag);
105 }
106
getTagName(uint32_t tag) const107 const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
108 ssize_t index = mTagToNameMap.indexOfKey(tag);
109 if (index < 0) {
110 return VENDOR_TAG_NAME_ERR;
111 }
112 return mTagToNameMap.valueAt(index).c_str();
113 }
114
getTagType(uint32_t tag) const115 int VendorTagDescriptor::getTagType(uint32_t tag) const {
116 auto iter = mTagToTypeMap.find(tag);
117 if (iter == mTagToTypeMap.end()) {
118 return VENDOR_TAG_TYPE_ERR;
119 }
120 return iter->second;
121 }
122
getAllSectionNames() const123 const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
124 return &mSections;
125 }
126
lookupTag(const String8 & name,const String8 & section,uint32_t * tag) const127 status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section,
128 /*out*/ uint32_t* tag) const {
129 ssize_t index = mReverseMapping.indexOfKey(section);
130 if (index < 0) {
131 ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.c_str());
132 return BAD_VALUE;
133 }
134
135 ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
136 if (nameIndex < 0) {
137 ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.c_str());
138 return BAD_VALUE;
139 }
140
141 if (tag != NULL) {
142 *tag = mReverseMapping[index]->valueAt(nameIndex);
143 }
144 return OK;
145 }
146
dump(int fd,int verbosity,int indentation) const147 void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
148 size_t size = mTagToNameMap.size();
149 if (size == 0) {
150 dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n", indentation, "");
151 return;
152 }
153
154 dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n", indentation, "",
155 size);
156 for (size_t i = 0; i < size; ++i) {
157 uint32_t tag = mTagToNameMap.keyAt(i);
158
159 if (verbosity < 1) {
160 dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
161 continue;
162 }
163 String8 name = mTagToNameMap.valueAt(i);
164 uint32_t sectionId = mTagToSectionMap.valueFor(tag);
165 String8 sectionName = mSections[sectionId];
166 int type = mTagToTypeMap.at(tag);
167 const char* typeName =
168 (type >= 0 && type < NUM_TYPES) ? camera_metadata_type_names[type] : "UNKNOWN";
169 dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2, "",
170 tag, name.c_str(), type, typeName, sectionName.c_str());
171 }
172 }
173
getTagCount(metadata_vendor_id_t id) const174 int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
175 int ret = 0;
176 auto desc = mVendorMap.find(id);
177 if (desc != mVendorMap.end()) {
178 ret = desc->second->getTagCount();
179 } else {
180 ALOGE("%s: Vendor descriptor id is missing!", __func__);
181 }
182
183 return ret;
184 }
185
getTagArray(uint32_t * tagArray,metadata_vendor_id_t id) const186 void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
187 auto desc = mVendorMap.find(id);
188 if (desc != mVendorMap.end()) {
189 desc->second->getTagArray(tagArray);
190 } else {
191 ALOGE("%s: Vendor descriptor id is missing!", __func__);
192 }
193 }
194
getSectionName(uint32_t tag,metadata_vendor_id_t id) const195 const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
196 const char* ret = nullptr;
197 auto desc = mVendorMap.find(id);
198 if (desc != mVendorMap.end()) {
199 ret = desc->second->getSectionName(tag);
200 } else {
201 ALOGE("%s: Vendor descriptor id is missing!", __func__);
202 }
203
204 return ret;
205 }
206
getTagName(uint32_t tag,metadata_vendor_id_t id) const207 const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
208 const char* ret = nullptr;
209 auto desc = mVendorMap.find(id);
210 if (desc != mVendorMap.end()) {
211 ret = desc->second->getTagName(tag);
212 } else {
213 ALOGE("%s: Vendor descriptor id is missing!", __func__);
214 }
215
216 return ret;
217 }
218
getTagType(uint32_t tag,metadata_vendor_id_t id) const219 int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
220 int ret = 0;
221 auto desc = mVendorMap.find(id);
222 if (desc != mVendorMap.end()) {
223 ret = desc->second->getTagType(tag);
224 } else {
225 ALOGE("%s: Vendor descriptor id is missing!", __func__);
226 }
227
228 return ret;
229 }
230
dump(int fd,int verbosity,int indentation) const231 void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
232 for (const auto& desc : mVendorMap) {
233 desc.second->dump(fd, verbosity, indentation);
234 }
235 }
236
addVendorDescriptor(metadata_vendor_id_t id,sp<hardware::camera::common::helper::VendorTagDescriptor> desc)237 int32_t VendorTagDescriptorCache::addVendorDescriptor(
238 metadata_vendor_id_t id, sp<hardware::camera::common::helper::VendorTagDescriptor> desc) {
239 auto entry = mVendorMap.find(id);
240 if (entry != mVendorMap.end()) {
241 ALOGE("%s: Vendor descriptor with same id already present!", __func__);
242 return BAD_VALUE;
243 }
244
245 mVendorMap.emplace(id, desc);
246 return NO_ERROR;
247 }
248
getVendorTagDescriptor(metadata_vendor_id_t id,sp<hardware::camera::common::helper::VendorTagDescriptor> * desc)249 int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
250 metadata_vendor_id_t id,
251 sp<hardware::camera::common::helper::VendorTagDescriptor>* desc /*out*/) {
252 auto entry = mVendorMap.find(id);
253 if (entry == mVendorMap.end()) {
254 return NAME_NOT_FOUND;
255 }
256
257 *desc = entry->second;
258
259 return NO_ERROR;
260 }
261 } // namespace params
262 } // namespace camera2
263
264 namespace camera {
265 namespace common {
266 namespace helper {
267
268 extern "C" {
269
270 static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
271 static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
272 static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
273 static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
274 static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
275
276 static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
277 static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
278 static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
279 metadata_vendor_id_t id);
280 static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
281 static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
282 } /* extern "C" */
283
284 static Mutex sLock;
285 static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
286 static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
287
createDescriptorFromOps(const vendor_tag_ops_t * vOps,sp<VendorTagDescriptor> & descriptor)288 status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
289 /*out*/
290 sp<VendorTagDescriptor>& descriptor) {
291 if (vOps == NULL) {
292 ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
293 return BAD_VALUE;
294 }
295
296 int tagCount = vOps->get_tag_count(vOps);
297 if (tagCount < 0 || tagCount > INT32_MAX) {
298 ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
299 return BAD_VALUE;
300 }
301
302 Vector<uint32_t> tagArray;
303 LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
304 "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
305
306 vOps->get_all_tags(vOps, /*out*/ tagArray.editArray());
307
308 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
309 desc->mTagCount = tagCount;
310
311 SortedVector<String8> sections;
312 KeyedVector<uint32_t, String8> tagToSectionMap;
313
314 for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
315 uint32_t tag = tagArray[i];
316 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
317 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
318 return BAD_VALUE;
319 }
320 const char* tagName = vOps->get_tag_name(vOps, tag);
321 if (tagName == NULL) {
322 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
323 return BAD_VALUE;
324 }
325 desc->mTagToNameMap.add(tag, String8(tagName));
326 const char* sectionName = vOps->get_section_name(vOps, tag);
327 if (sectionName == NULL) {
328 ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
329 return BAD_VALUE;
330 }
331
332 String8 sectionString(sectionName);
333
334 sections.add(sectionString);
335 tagToSectionMap.add(tag, sectionString);
336
337 int tagType = vOps->get_tag_type(vOps, tag);
338 if (tagType < 0 || tagType >= NUM_TYPES) {
339 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
340 return BAD_VALUE;
341 }
342 desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
343 }
344
345 desc->mSections = sections;
346
347 for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
348 uint32_t tag = tagArray[i];
349 const String8& sectionString = tagToSectionMap.valueFor(tag);
350
351 // Set up tag to section index map
352 ssize_t index = sections.indexOf(sectionString);
353 LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
354 desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
355
356 // Set up reverse mapping
357 ssize_t reverseIndex = -1;
358 if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
359 KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
360 reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
361 }
362 desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
363 }
364
365 descriptor = desc;
366 return OK;
367 }
368
setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor> & desc)369 status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
370 status_t res = OK;
371 Mutex::Autolock al(sLock);
372 sGlobalVendorTagDescriptor = desc;
373
374 vendor_tag_ops_t* opsPtr = NULL;
375 if (desc != NULL) {
376 opsPtr = &(desc->mVendorOps);
377 opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
378 opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
379 opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
380 opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
381 opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
382 }
383 if ((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
384 ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d).", __FUNCTION__,
385 strerror(-res), res);
386 }
387 return res;
388 }
389
clearGlobalVendorTagDescriptor()390 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
391 Mutex::Autolock al(sLock);
392 set_camera_metadata_vendor_ops(NULL);
393 sGlobalVendorTagDescriptor.clear();
394 }
395
getGlobalVendorTagDescriptor()396 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
397 Mutex::Autolock al(sLock);
398 return sGlobalVendorTagDescriptor;
399 }
400
setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache> & cache)401 status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
402 const sp<VendorTagDescriptorCache>& cache) {
403 status_t res = OK;
404 Mutex::Autolock al(sLock);
405 sGlobalVendorTagDescriptorCache = cache;
406
407 struct vendor_tag_cache_ops* opsPtr = NULL;
408 if (cache != NULL) {
409 opsPtr = &(cache->mVendorCacheOps);
410 opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
411 opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
412 opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
413 opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
414 opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
415 }
416 if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
417 ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
418 strerror(-res), res);
419 }
420 return res;
421 }
422
clearGlobalVendorTagCache()423 void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
424 Mutex::Autolock al(sLock);
425 set_camera_metadata_vendor_cache_ops(NULL);
426 sGlobalVendorTagDescriptorCache.clear();
427 }
428
getGlobalVendorTagCache()429 sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
430 Mutex::Autolock al(sLock);
431 return sGlobalVendorTagDescriptorCache;
432 }
433
434 extern "C" {
435
vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t *)436 int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
437 Mutex::Autolock al(sLock);
438 if (sGlobalVendorTagDescriptor == NULL) {
439 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
440 return VENDOR_TAG_COUNT_ERR;
441 }
442 return sGlobalVendorTagDescriptor->getTagCount();
443 }
444
vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t *,uint32_t * tagArray)445 void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
446 Mutex::Autolock al(sLock);
447 if (sGlobalVendorTagDescriptor == NULL) {
448 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
449 return;
450 }
451 sGlobalVendorTagDescriptor->getTagArray(tagArray);
452 }
453
vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t *,uint32_t tag)454 const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
455 Mutex::Autolock al(sLock);
456 if (sGlobalVendorTagDescriptor == NULL) {
457 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
458 return VENDOR_SECTION_NAME_ERR;
459 }
460 return sGlobalVendorTagDescriptor->getSectionName(tag);
461 }
462
vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t *,uint32_t tag)463 const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
464 Mutex::Autolock al(sLock);
465 if (sGlobalVendorTagDescriptor == NULL) {
466 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
467 return VENDOR_TAG_NAME_ERR;
468 }
469 return sGlobalVendorTagDescriptor->getTagName(tag);
470 }
471
vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t *,uint32_t tag)472 int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
473 Mutex::Autolock al(sLock);
474 if (sGlobalVendorTagDescriptor == NULL) {
475 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
476 return VENDOR_TAG_TYPE_ERR;
477 }
478 return sGlobalVendorTagDescriptor->getTagType(tag);
479 }
480
vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id)481 int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
482 Mutex::Autolock al(sLock);
483 if (sGlobalVendorTagDescriptorCache == NULL) {
484 ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
485 return VENDOR_TAG_COUNT_ERR;
486 }
487 return sGlobalVendorTagDescriptorCache->getTagCount(id);
488 }
489
vendor_tag_descriptor_cache_get_all_tags(uint32_t * tagArray,metadata_vendor_id_t id)490 void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
491 Mutex::Autolock al(sLock);
492 if (sGlobalVendorTagDescriptorCache == NULL) {
493 ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
494 }
495 sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
496 }
497
vendor_tag_descriptor_cache_get_section_name(uint32_t tag,metadata_vendor_id_t id)498 const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
499 Mutex::Autolock al(sLock);
500 if (sGlobalVendorTagDescriptorCache == NULL) {
501 ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
502 return VENDOR_SECTION_NAME_ERR;
503 }
504 return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
505 }
506
vendor_tag_descriptor_cache_get_tag_name(uint32_t tag,metadata_vendor_id_t id)507 const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
508 Mutex::Autolock al(sLock);
509 if (sGlobalVendorTagDescriptorCache == NULL) {
510 ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
511 return VENDOR_TAG_NAME_ERR;
512 }
513 return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
514 }
515
vendor_tag_descriptor_cache_get_tag_type(uint32_t tag,metadata_vendor_id_t id)516 int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
517 Mutex::Autolock al(sLock);
518 if (sGlobalVendorTagDescriptorCache == NULL) {
519 ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
520 return VENDOR_TAG_NAME_ERR;
521 }
522 return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
523 }
524
525 } /* extern "C" */
526
527 } // namespace helper
528 } // namespace common
529 } // namespace camera
530 } // namespace hardware
531 } // namespace android
532