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