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