1/*
2 * Copyright (C) 2014 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 "VendorTagDescriptor"
18
19#include <binder/Parcel.h>
20#include <utils/Errors.h>
21#include <utils/Log.h>
22#include <utils/Mutex.h>
23#include <utils/Vector.h>
24#include <utils/SortedVector.h>
25#include <system/camera_metadata.h>
26#include <camera_metadata_hidden.h>
27
28#include "camera/VendorTagDescriptor.h"
29
30#include <stdio.h>
31#include <string.h>
32#include <inttypes.h>
33
34namespace android {
35
36extern "C" {
37
38static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
39static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
40static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
41static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
42static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
43
44static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
45static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray,
46        metadata_vendor_id_t id);
47static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
48        metadata_vendor_id_t id);
49static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag,
50        metadata_vendor_id_t id);
51static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag,
52        metadata_vendor_id_t id);
53
54} /* extern "C" */
55
56
57static Mutex sLock;
58static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
59static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
60
61namespace hardware {
62namespace camera2 {
63namespace params {
64
65VendorTagDescriptor::~VendorTagDescriptor() {
66    size_t len = mReverseMapping.size();
67    for (size_t i = 0; i < len; ++i)  {
68        delete mReverseMapping[i];
69    }
70}
71
72VendorTagDescriptor::VendorTagDescriptor() :
73        mTagCount(0),
74        mVendorOps() {
75}
76
77VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
78    copyFrom(src);
79}
80
81VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
82    copyFrom(rhs);
83    return *this;
84}
85
86void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
87    if (this == &src) return;
88
89    size_t len = mReverseMapping.size();
90    for (size_t i = 0; i < len; ++i) {
91        delete mReverseMapping[i];
92    }
93    mReverseMapping.clear();
94
95    len = src.mReverseMapping.size();
96    // Have to copy KeyedVectors inside mReverseMapping
97    for (size_t i = 0; i < len; ++i) {
98        KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
99        *nameMapper = *(src.mReverseMapping.valueAt(i));
100        mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
101    }
102    // Everything else is simple
103    mTagToNameMap = src.mTagToNameMap;
104    mTagToSectionMap = src.mTagToSectionMap;
105    mTagToTypeMap = src.mTagToTypeMap;
106    mSections = src.mSections;
107    mTagCount = src.mTagCount;
108    mVendorOps = src.mVendorOps;
109}
110
111status_t VendorTagDescriptor::readFromParcel(const android::Parcel* parcel) {
112    status_t res = OK;
113    if (parcel == NULL) {
114        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
115        return BAD_VALUE;
116    }
117
118    int32_t tagCount = 0;
119    if ((res = parcel->readInt32(&tagCount)) != OK) {
120        ALOGE("%s: could not read tag count from parcel", __FUNCTION__);
121        return res;
122    }
123
124    if (tagCount < 0 || tagCount > INT32_MAX) {
125        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
126        return BAD_VALUE;
127    }
128
129    mTagCount = tagCount;
130
131    uint32_t tag, sectionIndex;
132    uint32_t maxSectionIndex = 0;
133    int32_t tagType;
134    Vector<uint32_t> allTags;
135    for (int32_t i = 0; i < tagCount; ++i) {
136        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) {
137            ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i);
138            break;
139        }
140        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
141            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
142            res = BAD_VALUE;
143            break;
144        }
145        if ((res = parcel->readInt32(&tagType)) != OK) {
146            ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag);
147            break;
148        }
149        if (tagType < 0 || tagType >= NUM_TYPES) {
150            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
151            res = BAD_VALUE;
152            break;
153        }
154        String8 tagName = parcel->readString8();
155        if (tagName.isEmpty()) {
156            ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag);
157            res = NOT_ENOUGH_DATA;
158            break;
159        }
160
161        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionIndex))) != OK) {
162            ALOGE("%s: could not read section index for tag %d.", __FUNCTION__, tag);
163            break;
164        }
165
166        maxSectionIndex = (maxSectionIndex >= sectionIndex) ? maxSectionIndex : sectionIndex;
167
168        allTags.add(tag);
169        mTagToNameMap.add(tag, tagName);
170        mTagToSectionMap.add(tag, sectionIndex);
171        mTagToTypeMap.add(tag, tagType);
172    }
173
174    if (res != OK) {
175        return res;
176    }
177
178    size_t sectionCount = 0;
179    if (tagCount > 0) {
180        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionCount))) != OK) {
181            ALOGE("%s: could not read section count for.", __FUNCTION__);
182            return res;
183        }
184        if (sectionCount < (maxSectionIndex + 1)) {
185            ALOGE("%s: Incorrect number of sections defined, received %zu, needs %d.",
186                    __FUNCTION__, sectionCount, (maxSectionIndex + 1));
187            return BAD_VALUE;
188        }
189        LOG_ALWAYS_FATAL_IF(mSections.setCapacity(sectionCount) <= 0,
190                "Vector capacity must be positive");
191        for (size_t i = 0; i < sectionCount; ++i) {
192            String8 sectionName = parcel->readString8();
193            if (sectionName.isEmpty()) {
194                ALOGE("%s: parcel section name was NULL for section %zu.",
195                      __FUNCTION__, i);
196                return NOT_ENOUGH_DATA;
197            }
198            mSections.add(sectionName);
199        }
200    }
201
202    LOG_ALWAYS_FATAL_IF(static_cast<size_t>(tagCount) != allTags.size(),
203                        "tagCount must be the same as allTags size");
204    // Set up reverse mapping
205    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
206        uint32_t tag = allTags[i];
207        const String8& sectionString = mSections[mTagToSectionMap.valueFor(tag)];
208
209        ssize_t reverseIndex = -1;
210        if ((reverseIndex = mReverseMapping.indexOfKey(sectionString)) < 0) {
211            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
212            reverseIndex = mReverseMapping.add(sectionString, nameMapper);
213        }
214        mReverseMapping[reverseIndex]->add(mTagToNameMap.valueFor(tag), tag);
215    }
216
217    return res;
218}
219
220int VendorTagDescriptor::getTagCount() const {
221    size_t size = mTagToNameMap.size();
222    if (size == 0) {
223        return VENDOR_TAG_COUNT_ERR;
224    }
225    return size;
226}
227
228void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
229    size_t size = mTagToNameMap.size();
230    for (size_t i = 0; i < size; ++i) {
231        tagArray[i] = mTagToNameMap.keyAt(i);
232    }
233}
234
235const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
236    ssize_t index = mTagToSectionMap.indexOfKey(tag);
237    if (index < 0) {
238        return VENDOR_SECTION_NAME_ERR;
239    }
240    return mSections[mTagToSectionMap.valueAt(index)].string();
241}
242
243const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
244    ssize_t index = mTagToNameMap.indexOfKey(tag);
245    if (index < 0) {
246        return VENDOR_TAG_NAME_ERR;
247    }
248    return mTagToNameMap.valueAt(index).string();
249}
250
251int VendorTagDescriptor::getTagType(uint32_t tag) const {
252    ssize_t index = mTagToNameMap.indexOfKey(tag);
253    if (index < 0) {
254        return VENDOR_TAG_TYPE_ERR;
255    }
256    return mTagToTypeMap.valueFor(tag);
257}
258
259status_t VendorTagDescriptor::writeToParcel(android::Parcel* parcel) const {
260    status_t res = OK;
261    if (parcel == NULL) {
262        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
263        return BAD_VALUE;
264    }
265
266    if ((res = parcel->writeInt32(mTagCount)) != OK) {
267        return res;
268    }
269
270    size_t size = mTagToNameMap.size();
271    uint32_t tag, sectionIndex;
272    int32_t tagType;
273    for (size_t i = 0; i < size; ++i) {
274        tag = mTagToNameMap.keyAt(i);
275        String8 tagName = mTagToNameMap[i];
276        sectionIndex = mTagToSectionMap.valueFor(tag);
277        tagType = mTagToTypeMap.valueFor(tag);
278        if ((res = parcel->writeInt32(tag)) != OK) break;
279        if ((res = parcel->writeInt32(tagType)) != OK) break;
280        if ((res = parcel->writeString8(tagName)) != OK) break;
281        if ((res = parcel->writeInt32(sectionIndex)) != OK) break;
282    }
283
284    size_t numSections = mSections.size();
285    if (numSections > 0) {
286        if ((res = parcel->writeInt32(numSections)) != OK) return res;
287        for (size_t i = 0; i < numSections; ++i) {
288            if ((res = parcel->writeString8(mSections[i])) != OK) return res;
289        }
290    }
291
292    return res;
293}
294
295const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
296    return &mSections;
297}
298
299status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const {
300    ssize_t index = mReverseMapping.indexOfKey(section);
301    if (index < 0) {
302        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
303        return BAD_VALUE;
304    }
305
306    ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
307    if (nameIndex < 0) {
308        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
309        return BAD_VALUE;
310    }
311
312    if (tag != NULL) {
313        *tag = mReverseMapping[index]->valueAt(nameIndex);
314    }
315    return OK;
316}
317
318void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
319
320    size_t size = mTagToNameMap.size();
321    if (size == 0) {
322        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
323                indentation, "");
324        return;
325    }
326
327    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
328            indentation, "", size);
329    for (size_t i = 0; i < size; ++i) {
330        uint32_t tag =  mTagToNameMap.keyAt(i);
331
332        if (verbosity < 1) {
333            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
334            continue;
335        }
336        String8 name = mTagToNameMap.valueAt(i);
337        uint32_t sectionId = mTagToSectionMap.valueFor(tag);
338        String8 sectionName = mSections[sectionId];
339        int type = mTagToTypeMap.valueFor(tag);
340        const char* typeName = (type >= 0 && type < NUM_TYPES) ?
341                camera_metadata_type_names[type] : "UNKNOWN";
342        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
343            "", tag, name.string(), type, typeName, sectionName.string());
344    }
345
346}
347
348status_t VendorTagDescriptorCache::writeToParcel(Parcel* parcel) const {
349    status_t res = OK;
350    if (parcel == NULL) {
351        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
352        return BAD_VALUE;
353    }
354
355    if ((res = parcel->writeInt32(mVendorMap.size())) != OK) {
356        return res;
357    }
358
359    for (const auto &iter : mVendorMap) {
360        if ((res = parcel->writeUint64(iter.first)) != OK) break;
361        if ((res = parcel->writeParcelable(*iter.second)) != OK) break;
362    }
363
364    return res;
365}
366
367
368status_t VendorTagDescriptorCache::readFromParcel(const Parcel* parcel) {
369    status_t res = OK;
370    if (parcel == NULL) {
371        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
372        return BAD_VALUE;
373    }
374
375    int32_t vendorCount = 0;
376    if ((res = parcel->readInt32(&vendorCount)) != OK) {
377        ALOGE("%s: could not read vendor count from parcel", __FUNCTION__);
378        return res;
379    }
380
381    if (vendorCount < 0 || vendorCount > INT32_MAX) {
382        ALOGE("%s: vendor count %d from is invalid.", __FUNCTION__, vendorCount);
383        return BAD_VALUE;
384    }
385
386    metadata_vendor_id_t id;
387    for (int32_t i = 0; i < vendorCount; i++) {
388        if ((res = parcel->readUint64(&id)) != OK) {
389            ALOGE("%s: could not read vendor id from parcel for index %d",
390                  __FUNCTION__, i);
391            break;
392        }
393        sp<android::VendorTagDescriptor> desc = new android::VendorTagDescriptor();
394        if ((res = parcel->readParcelable(desc.get())) != OK) {
395            ALOGE("%s: could not read vendor tag descriptor from parcel for index %d rc = %d",
396                  __FUNCTION__, i, res);
397            break;
398        }
399
400        if ((res = addVendorDescriptor(id, desc)) != OK) {
401            ALOGE("%s: failed to add vendor tag descriptor for index: %d ",
402                  __FUNCTION__, i);
403            break;
404        }
405    }
406
407    return res;
408}
409
410int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
411    int ret = 0;
412    auto desc = mVendorMap.find(id);
413    if (desc != mVendorMap.end()) {
414        ret = desc->second->getTagCount();
415    } else {
416        ALOGE("%s: Vendor descriptor id is missing!", __func__);
417    }
418
419    return ret;
420}
421
422void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray,
423        metadata_vendor_id_t id) const {
424    auto desc = mVendorMap.find(id);
425    if (desc != mVendorMap.end()) {
426        desc->second->getTagArray(tagArray);
427    } else {
428        ALOGE("%s: Vendor descriptor id is missing!", __func__);
429    }
430}
431
432const char* VendorTagDescriptorCache::getSectionName(uint32_t tag,
433        metadata_vendor_id_t id) const {
434    const char *ret = nullptr;
435    auto desc = mVendorMap.find(id);
436    if (desc != mVendorMap.end()) {
437        ret = desc->second->getSectionName(tag);
438    } else {
439        ALOGE("%s: Vendor descriptor id is missing!", __func__);
440    }
441
442    return ret;
443}
444
445const char* VendorTagDescriptorCache::getTagName(uint32_t tag,
446        metadata_vendor_id_t id) const {
447    const char *ret = nullptr;
448    auto desc = mVendorMap.find(id);
449    if (desc != mVendorMap.end()) {
450        ret = desc->second->getTagName(tag);
451    } else {
452        ALOGE("%s: Vendor descriptor id is missing!", __func__);
453    }
454
455    return ret;
456}
457
458int VendorTagDescriptorCache::getTagType(uint32_t tag,
459        metadata_vendor_id_t id) const {
460    int ret = 0;
461    auto desc = mVendorMap.find(id);
462    if (desc != mVendorMap.end()) {
463        ret = desc->second->getTagType(tag);
464    } else {
465        ALOGE("%s: Vendor descriptor id is missing!", __func__);
466    }
467
468    return ret;
469}
470
471void VendorTagDescriptorCache::dump(int fd, int verbosity,
472        int indentation) const {
473    for (const auto &desc : mVendorMap) {
474        dprintf(fd, "%*sDumping vendor tag descriptors for vendor with"
475                " id %" PRIu64 " \n", indentation, "", desc.first);
476        desc.second->dump(fd, verbosity, indentation);
477    }
478}
479
480int32_t VendorTagDescriptorCache::addVendorDescriptor(metadata_vendor_id_t id,
481        sp<android::VendorTagDescriptor> desc) {
482    auto entry = mVendorMap.find(id);
483    if (entry != mVendorMap.end()) {
484        ALOGE("%s: Vendor descriptor with same id already present!", __func__);
485        return BAD_VALUE;
486    }
487
488    mVendorMap.emplace(id, desc);
489    return NO_ERROR;
490}
491
492int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
493        metadata_vendor_id_t id, sp<android::VendorTagDescriptor> *desc /*out*/) {
494    auto entry = mVendorMap.find(id);
495    if (entry == mVendorMap.end()) {
496        return NAME_NOT_FOUND;
497    }
498
499    *desc = entry->second;
500
501    return NO_ERROR;
502}
503
504} // namespace params
505} // namespace camera2
506} // namespace hardware
507
508status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
509            /*out*/
510            sp<VendorTagDescriptor>& descriptor) {
511    if (vOps == NULL) {
512        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
513        return BAD_VALUE;
514    }
515
516    int tagCount = vOps->get_tag_count(vOps);
517    if (tagCount < 0 || tagCount > INT32_MAX) {
518        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
519        return BAD_VALUE;
520    }
521
522    Vector<uint32_t> tagArray;
523    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
524            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
525
526    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
527
528    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
529    desc->mTagCount = tagCount;
530
531    SortedVector<String8> sections;
532    KeyedVector<uint32_t, String8> tagToSectionMap;
533
534    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
535        uint32_t tag = tagArray[i];
536        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
537            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
538            return BAD_VALUE;
539        }
540        const char *tagName = vOps->get_tag_name(vOps, tag);
541        if (tagName == NULL) {
542            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
543            return BAD_VALUE;
544        }
545        desc->mTagToNameMap.add(tag, String8(tagName));
546        const char *sectionName = vOps->get_section_name(vOps, tag);
547        if (sectionName == NULL) {
548            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
549            return BAD_VALUE;
550        }
551
552        String8 sectionString(sectionName);
553
554        sections.add(sectionString);
555        tagToSectionMap.add(tag, sectionString);
556
557        int tagType = vOps->get_tag_type(vOps, tag);
558        if (tagType < 0 || tagType >= NUM_TYPES) {
559            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
560            return BAD_VALUE;
561        }
562        desc->mTagToTypeMap.add(tag, tagType);
563    }
564
565    desc->mSections = sections;
566
567    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
568        uint32_t tag = tagArray[i];
569        String8 sectionString = tagToSectionMap.valueFor(tag);
570
571        // Set up tag to section index map
572        ssize_t index = sections.indexOf(sectionString);
573        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
574        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
575
576        // Set up reverse mapping
577        ssize_t reverseIndex = -1;
578        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
579            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
580            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
581        }
582        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
583    }
584
585    descriptor = desc;
586    return OK;
587}
588
589status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
590    status_t res = OK;
591    Mutex::Autolock al(sLock);
592    sGlobalVendorTagDescriptor = desc;
593
594    vendor_tag_ops_t* opsPtr = NULL;
595    if (desc != NULL) {
596        opsPtr = &(desc->mVendorOps);
597        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
598        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
599        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
600        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
601        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
602    }
603    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
604        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
605                , __FUNCTION__, strerror(-res), res);
606    }
607    return res;
608}
609
610void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
611    Mutex::Autolock al(sLock);
612    set_camera_metadata_vendor_ops(NULL);
613    sGlobalVendorTagDescriptor.clear();
614}
615
616sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
617    Mutex::Autolock al(sLock);
618    return sGlobalVendorTagDescriptor;
619}
620
621status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
622        const sp<VendorTagDescriptorCache>& cache) {
623    status_t res = OK;
624    Mutex::Autolock al(sLock);
625    sGlobalVendorTagDescriptorCache = cache;
626
627    struct vendor_tag_cache_ops* opsPtr = NULL;
628    if (cache != NULL) {
629        opsPtr = &(cache->mVendorCacheOps);
630        opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
631        opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
632        opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
633        opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
634        opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
635    }
636    if((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
637        ALOGE("%s: Could not set vendor tag cache, received error %s (%d)."
638                , __FUNCTION__, strerror(-res), res);
639    }
640    return res;
641}
642
643void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
644    Mutex::Autolock al(sLock);
645    set_camera_metadata_vendor_cache_ops(NULL);
646    sGlobalVendorTagDescriptorCache.clear();
647}
648
649sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
650    Mutex::Autolock al(sLock);
651    return sGlobalVendorTagDescriptorCache;
652}
653
654extern "C" {
655
656int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
657    Mutex::Autolock al(sLock);
658    if (sGlobalVendorTagDescriptor == NULL) {
659        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
660        return VENDOR_TAG_COUNT_ERR;
661    }
662    return sGlobalVendorTagDescriptor->getTagCount();
663}
664
665void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
666    Mutex::Autolock al(sLock);
667    if (sGlobalVendorTagDescriptor == NULL) {
668        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
669        return;
670    }
671    sGlobalVendorTagDescriptor->getTagArray(tagArray);
672}
673
674const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
675    Mutex::Autolock al(sLock);
676    if (sGlobalVendorTagDescriptor == NULL) {
677        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
678        return VENDOR_SECTION_NAME_ERR;
679    }
680    return sGlobalVendorTagDescriptor->getSectionName(tag);
681}
682
683const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
684    Mutex::Autolock al(sLock);
685    if (sGlobalVendorTagDescriptor == NULL) {
686        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
687        return VENDOR_TAG_NAME_ERR;
688    }
689    return sGlobalVendorTagDescriptor->getTagName(tag);
690}
691
692int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
693    Mutex::Autolock al(sLock);
694    if (sGlobalVendorTagDescriptor == NULL) {
695        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
696        return VENDOR_TAG_TYPE_ERR;
697    }
698    return sGlobalVendorTagDescriptor->getTagType(tag);
699}
700
701int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
702    Mutex::Autolock al(sLock);
703    if (sGlobalVendorTagDescriptorCache == NULL) {
704        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
705        return VENDOR_TAG_COUNT_ERR;
706    }
707    return sGlobalVendorTagDescriptorCache->getTagCount(id);
708}
709
710void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray,
711        metadata_vendor_id_t id) {
712    Mutex::Autolock al(sLock);
713    if (sGlobalVendorTagDescriptorCache == NULL) {
714        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
715    }
716    sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
717}
718
719const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
720        metadata_vendor_id_t id) {
721    Mutex::Autolock al(sLock);
722    if (sGlobalVendorTagDescriptorCache == NULL) {
723        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
724        return VENDOR_SECTION_NAME_ERR;
725    }
726    return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
727}
728
729const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag,
730        metadata_vendor_id_t id) {
731    Mutex::Autolock al(sLock);
732    if (sGlobalVendorTagDescriptorCache == NULL) {
733        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
734        return VENDOR_TAG_NAME_ERR;
735    }
736    return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
737}
738
739int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag,
740        metadata_vendor_id_t id) {
741    Mutex::Autolock al(sLock);
742    if (sGlobalVendorTagDescriptorCache == NULL) {
743        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
744        return VENDOR_TAG_NAME_ERR;
745    }
746    return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
747}
748
749} /* extern "C" */
750} /* namespace android */
751