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