VendorTagDescriptor.cpp revision 0c629a3857c31bee6fa39ba7a9a8cbcabeb383fd
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
33namespace android {
34
35extern "C" {
36
37static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
38static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
39static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
40static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
41static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
42
43} /* extern "C" */
44
45
46static Mutex sLock;
47static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
48
49VendorTagDescriptor::VendorTagDescriptor() {}
50
51VendorTagDescriptor::~VendorTagDescriptor() {
52    size_t len = mReverseMapping.size();
53    for (size_t i = 0; i < len; ++i)  {
54        delete mReverseMapping[i];
55    }
56}
57
58status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
59            /*out*/
60            sp<VendorTagDescriptor>& descriptor) {
61    if (vOps == NULL) {
62        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
63        return BAD_VALUE;
64    }
65
66    int tagCount = vOps->get_tag_count(vOps);
67    if (tagCount < 0 || tagCount > INT32_MAX) {
68        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
69        return BAD_VALUE;
70    }
71
72    Vector<uint32_t> tagArray;
73    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
74            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
75
76    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
77
78    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
79    desc->mTagCount = tagCount;
80
81    SortedVector<String8> sections;
82    KeyedVector<uint32_t, String8> tagToSectionMap;
83
84    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
85        uint32_t tag = tagArray[i];
86        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
87            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
88            return BAD_VALUE;
89        }
90        const char *tagName = vOps->get_tag_name(vOps, tag);
91        if (tagName == NULL) {
92            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
93            return BAD_VALUE;
94        }
95        desc->mTagToNameMap.add(tag, String8(tagName));
96        const char *sectionName = vOps->get_section_name(vOps, tag);
97        if (sectionName == NULL) {
98            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
99            return BAD_VALUE;
100        }
101
102        String8 sectionString(sectionName);
103
104        sections.add(sectionString);
105        tagToSectionMap.add(tag, sectionString);
106
107        int tagType = vOps->get_tag_type(vOps, tag);
108        if (tagType < 0 || tagType >= NUM_TYPES) {
109            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
110            return BAD_VALUE;
111        }
112        desc->mTagToTypeMap.add(tag, tagType);
113    }
114
115    desc->mSections = sections;
116
117    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
118        uint32_t tag = tagArray[i];
119        String8 sectionString = tagToSectionMap.valueFor(tag);
120
121        // Set up tag to section index map
122        ssize_t index = sections.indexOf(sectionString);
123        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
124        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
125
126        // Set up reverse mapping
127        ssize_t reverseIndex = -1;
128        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
129            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
130            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
131        }
132        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
133    }
134
135    descriptor = desc;
136    return OK;
137}
138
139status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel,
140            /*out*/
141            sp<VendorTagDescriptor>& descriptor) {
142    status_t res = OK;
143    if (parcel == NULL) {
144        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
145        return BAD_VALUE;
146    }
147
148    int32_t tagCount = 0;
149    if ((res = parcel->readInt32(&tagCount)) != OK) {
150        ALOGE("%s: could not read tag count from parcel", __FUNCTION__);
151        return res;
152    }
153
154    if (tagCount < 0 || tagCount > INT32_MAX) {
155        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
156        return BAD_VALUE;
157    }
158
159    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
160    desc->mTagCount = tagCount;
161
162    uint32_t tag, sectionIndex;
163    uint32_t maxSectionIndex = 0;
164    int32_t tagType;
165    Vector<uint32_t> allTags;
166    for (int32_t i = 0; i < tagCount; ++i) {
167        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) {
168            ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i);
169            break;
170        }
171        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
172            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
173            res = BAD_VALUE;
174            break;
175        }
176        if ((res = parcel->readInt32(&tagType)) != OK) {
177            ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag);
178            break;
179        }
180        if (tagType < 0 || tagType >= NUM_TYPES) {
181            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
182            res = BAD_VALUE;
183            break;
184        }
185        String8 tagName = parcel->readString8();
186        if (tagName.isEmpty()) {
187            ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag);
188            res = NOT_ENOUGH_DATA;
189            break;
190        }
191
192        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionIndex))) != OK) {
193            ALOGE("%s: could not read section index for tag %d.", __FUNCTION__, tag);
194            break;
195        }
196
197        maxSectionIndex = (maxSectionIndex >= sectionIndex) ? maxSectionIndex : sectionIndex;
198
199        allTags.add(tag);
200        desc->mTagToNameMap.add(tag, tagName);
201        desc->mTagToSectionMap.add(tag, sectionIndex);
202        desc->mTagToTypeMap.add(tag, tagType);
203    }
204
205    if (res != OK) {
206        return res;
207    }
208
209    size_t sectionCount = 0;
210    if (tagCount > 0) {
211        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionCount))) != OK) {
212            ALOGE("%s: could not read section count for.", __FUNCTION__);
213            return res;
214        }
215        if (sectionCount < (maxSectionIndex + 1)) {
216            ALOGE("%s: Incorrect number of sections defined, received %zu, needs %d.",
217                    __FUNCTION__, sectionCount, (maxSectionIndex + 1));
218            return BAD_VALUE;
219        }
220        LOG_ALWAYS_FATAL_IF(desc->mSections.setCapacity(sectionCount) <= 0,
221                "Vector capacity must be positive");
222        for (size_t i = 0; i < sectionCount; ++i) {
223            String8 sectionName = parcel->readString8();
224            if (sectionName.isEmpty()) {
225                ALOGE("%s: parcel section name was NULL for section %zu.",
226                      __FUNCTION__, i);
227                return NOT_ENOUGH_DATA;
228            }
229            desc->mSections.add(sectionName);
230        }
231    }
232
233    LOG_ALWAYS_FATAL_IF(static_cast<size_t>(tagCount) != allTags.size(),
234                        "tagCount must be the same as allTags size");
235    // Set up reverse mapping
236    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
237        uint32_t tag = allTags[i];
238        String8 sectionString = desc->mSections[desc->mTagToSectionMap.valueFor(tag)];
239
240        ssize_t reverseIndex = -1;
241        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
242            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
243            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
244        }
245        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
246    }
247
248    descriptor = desc;
249    return res;
250}
251
252int VendorTagDescriptor::getTagCount() const {
253    size_t size = mTagToNameMap.size();
254    if (size == 0) {
255        return VENDOR_TAG_COUNT_ERR;
256    }
257    return size;
258}
259
260void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
261    size_t size = mTagToNameMap.size();
262    for (size_t i = 0; i < size; ++i) {
263        tagArray[i] = mTagToNameMap.keyAt(i);
264    }
265}
266
267const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
268    ssize_t index = mTagToSectionMap.indexOfKey(tag);
269    if (index < 0) {
270        return VENDOR_SECTION_NAME_ERR;
271    }
272    return mSections[mTagToSectionMap.valueAt(index)].string();
273}
274
275const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
276    ssize_t index = mTagToNameMap.indexOfKey(tag);
277    if (index < 0) {
278        return VENDOR_TAG_NAME_ERR;
279    }
280    return mTagToNameMap.valueAt(index).string();
281}
282
283int VendorTagDescriptor::getTagType(uint32_t tag) const {
284    ssize_t index = mTagToNameMap.indexOfKey(tag);
285    if (index < 0) {
286        return VENDOR_TAG_TYPE_ERR;
287    }
288    return mTagToTypeMap.valueFor(tag);
289}
290
291status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const {
292    status_t res = OK;
293    if (parcel == NULL) {
294        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
295        return BAD_VALUE;
296    }
297
298    if ((res = parcel->writeInt32(mTagCount)) != OK) {
299        return res;
300    }
301
302    size_t size = mTagToNameMap.size();
303    uint32_t tag, sectionIndex;
304    int32_t tagType;
305    for (size_t i = 0; i < size; ++i) {
306        tag = mTagToNameMap.keyAt(i);
307        String8 tagName = mTagToNameMap[i];
308        sectionIndex = mTagToSectionMap.valueFor(tag);
309        tagType = mTagToTypeMap.valueFor(tag);
310        if ((res = parcel->writeInt32(tag)) != OK) break;
311        if ((res = parcel->writeInt32(tagType)) != OK) break;
312        if ((res = parcel->writeString8(tagName)) != OK) break;
313        if ((res = parcel->writeInt32(sectionIndex)) != OK) break;
314    }
315
316    size_t numSections = mSections.size();
317    if (numSections > 0) {
318        if ((res = parcel->writeInt32(numSections)) != OK) return res;
319        for (size_t i = 0; i < numSections; ++i) {
320            if ((res = parcel->writeString8(mSections[i])) != OK) return res;
321        }
322    }
323
324    return res;
325}
326
327SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
328    return mSections;
329}
330
331status_t VendorTagDescriptor::lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const {
332    ssize_t index = mReverseMapping.indexOfKey(section);
333    if (index < 0) {
334        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
335        return BAD_VALUE;
336    }
337
338    ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
339    if (nameIndex < 0) {
340        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
341        return BAD_VALUE;
342    }
343
344    if (tag != NULL) {
345        *tag = mReverseMapping[index]->valueAt(nameIndex);
346    }
347    return OK;
348}
349
350void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
351
352    size_t size = mTagToNameMap.size();
353    if (size == 0) {
354        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
355                indentation, "");
356        return;
357    }
358
359    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
360            indentation, "", size);
361    for (size_t i = 0; i < size; ++i) {
362        uint32_t tag =  mTagToNameMap.keyAt(i);
363
364        if (verbosity < 1) {
365            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
366            continue;
367        }
368        String8 name = mTagToNameMap.valueAt(i);
369        uint32_t sectionId = mTagToSectionMap.valueFor(tag);
370        String8 sectionName = mSections[sectionId];
371        int type = mTagToTypeMap.valueFor(tag);
372        const char* typeName = (type >= 0 && type < NUM_TYPES) ?
373                camera_metadata_type_names[type] : "UNKNOWN";
374        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
375            "", tag, name.string(), type, typeName, sectionName.string());
376    }
377
378}
379
380status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
381    status_t res = OK;
382    Mutex::Autolock al(sLock);
383    sGlobalVendorTagDescriptor = desc;
384
385    vendor_tag_ops_t* opsPtr = NULL;
386    if (desc != NULL) {
387        opsPtr = &(desc->mVendorOps);
388        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
389        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
390        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
391        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
392        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
393    }
394    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
395        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
396                , __FUNCTION__, strerror(-res), res);
397    }
398    return res;
399}
400
401void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
402    Mutex::Autolock al(sLock);
403    set_camera_metadata_vendor_ops(NULL);
404    sGlobalVendorTagDescriptor.clear();
405}
406
407sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
408    Mutex::Autolock al(sLock);
409    return sGlobalVendorTagDescriptor;
410}
411
412extern "C" {
413
414int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
415    Mutex::Autolock al(sLock);
416    if (sGlobalVendorTagDescriptor == NULL) {
417        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
418        return VENDOR_TAG_COUNT_ERR;
419    }
420    return sGlobalVendorTagDescriptor->getTagCount();
421}
422
423void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
424    Mutex::Autolock al(sLock);
425    if (sGlobalVendorTagDescriptor == NULL) {
426        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
427        return;
428    }
429    sGlobalVendorTagDescriptor->getTagArray(tagArray);
430}
431
432const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
433    Mutex::Autolock al(sLock);
434    if (sGlobalVendorTagDescriptor == NULL) {
435        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
436        return VENDOR_SECTION_NAME_ERR;
437    }
438    return sGlobalVendorTagDescriptor->getSectionName(tag);
439}
440
441const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
442    Mutex::Autolock al(sLock);
443    if (sGlobalVendorTagDescriptor == NULL) {
444        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
445        return VENDOR_TAG_NAME_ERR;
446    }
447    return sGlobalVendorTagDescriptor->getTagName(tag);
448}
449
450int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
451    Mutex::Autolock al(sLock);
452    if (sGlobalVendorTagDescriptor == NULL) {
453        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
454        return VENDOR_TAG_TYPE_ERR;
455    }
456    return sGlobalVendorTagDescriptor->getTagType(tag);
457}
458
459} /* extern "C" */
460} /* namespace android */
461