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
32namespace android {
33namespace hardware {
34namespace camera2 {
35namespace params {
36
37VendorTagDescriptor::~VendorTagDescriptor() {
38    size_t len = mReverseMapping.size();
39    for (size_t i = 0; i < len; ++i)  {
40        delete mReverseMapping[i];
41    }
42}
43
44VendorTagDescriptor::VendorTagDescriptor() :
45        mTagCount(0),
46        mVendorOps() {
47}
48
49VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
50    copyFrom(src);
51}
52
53VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
54    copyFrom(rhs);
55    return *this;
56}
57
58void 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
83int 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
91void 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
98const 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
106ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
107    return mTagToSectionMap.valueFor(tag);
108}
109
110const 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
118int VendorTagDescriptor::getTagType(uint32_t tag) const {
119    ssize_t index = mTagToNameMap.indexOfKey(tag);
120    if (index < 0) {
121        return VENDOR_TAG_TYPE_ERR;
122    }
123    return mTagToTypeMap.valueFor(tag);
124}
125
126const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
127    return &mSections;
128}
129
130status_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
149void 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.valueFor(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
179} // namespace params
180} // namespace camera2
181
182namespace camera {
183namespace common {
184namespace V1_0 {
185namespace helper {
186
187extern "C" {
188
189static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
190static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
191static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
192static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
193static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
194
195} /* extern "C" */
196
197static Mutex sLock;
198static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
199
200status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
201            /*out*/
202            sp<VendorTagDescriptor>& descriptor) {
203    if (vOps == NULL) {
204        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
205        return BAD_VALUE;
206    }
207
208    int tagCount = vOps->get_tag_count(vOps);
209    if (tagCount < 0 || tagCount > INT32_MAX) {
210        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
211        return BAD_VALUE;
212    }
213
214    Vector<uint32_t> tagArray;
215    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
216            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
217
218    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
219
220    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
221    desc->mTagCount = tagCount;
222
223    SortedVector<String8> sections;
224    KeyedVector<uint32_t, String8> tagToSectionMap;
225
226    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
227        uint32_t tag = tagArray[i];
228        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
229            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
230            return BAD_VALUE;
231        }
232        const char *tagName = vOps->get_tag_name(vOps, tag);
233        if (tagName == NULL) {
234            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
235            return BAD_VALUE;
236        }
237        desc->mTagToNameMap.add(tag, String8(tagName));
238        const char *sectionName = vOps->get_section_name(vOps, tag);
239        if (sectionName == NULL) {
240            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
241            return BAD_VALUE;
242        }
243
244        String8 sectionString(sectionName);
245
246        sections.add(sectionString);
247        tagToSectionMap.add(tag, sectionString);
248
249        int tagType = vOps->get_tag_type(vOps, tag);
250        if (tagType < 0 || tagType >= NUM_TYPES) {
251            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
252            return BAD_VALUE;
253        }
254        desc->mTagToTypeMap.add(tag, tagType);
255    }
256
257    desc->mSections = sections;
258
259    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
260        uint32_t tag = tagArray[i];
261        String8 sectionString = tagToSectionMap.valueFor(tag);
262
263        // Set up tag to section index map
264        ssize_t index = sections.indexOf(sectionString);
265        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
266        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
267
268        // Set up reverse mapping
269        ssize_t reverseIndex = -1;
270        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
271            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
272            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
273        }
274        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
275    }
276
277    descriptor = desc;
278    return OK;
279}
280
281status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
282    status_t res = OK;
283    Mutex::Autolock al(sLock);
284    sGlobalVendorTagDescriptor = desc;
285
286    vendor_tag_ops_t* opsPtr = NULL;
287    if (desc != NULL) {
288        opsPtr = &(desc->mVendorOps);
289        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
290        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
291        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
292        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
293        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
294    }
295    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
296        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
297                , __FUNCTION__, strerror(-res), res);
298    }
299    return res;
300}
301
302void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
303    Mutex::Autolock al(sLock);
304    set_camera_metadata_vendor_ops(NULL);
305    sGlobalVendorTagDescriptor.clear();
306}
307
308sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
309    Mutex::Autolock al(sLock);
310    return sGlobalVendorTagDescriptor;
311}
312
313extern "C" {
314
315int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
316    Mutex::Autolock al(sLock);
317    if (sGlobalVendorTagDescriptor == NULL) {
318        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
319        return VENDOR_TAG_COUNT_ERR;
320    }
321    return sGlobalVendorTagDescriptor->getTagCount();
322}
323
324void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
325    Mutex::Autolock al(sLock);
326    if (sGlobalVendorTagDescriptor == NULL) {
327        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
328        return;
329    }
330    sGlobalVendorTagDescriptor->getTagArray(tagArray);
331}
332
333const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
334    Mutex::Autolock al(sLock);
335    if (sGlobalVendorTagDescriptor == NULL) {
336        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
337        return VENDOR_SECTION_NAME_ERR;
338    }
339    return sGlobalVendorTagDescriptor->getSectionName(tag);
340}
341
342const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
343    Mutex::Autolock al(sLock);
344    if (sGlobalVendorTagDescriptor == NULL) {
345        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
346        return VENDOR_TAG_NAME_ERR;
347    }
348    return sGlobalVendorTagDescriptor->getTagName(tag);
349}
350
351int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
352    Mutex::Autolock al(sLock);
353    if (sGlobalVendorTagDescriptor == NULL) {
354        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
355        return VENDOR_TAG_TYPE_ERR;
356    }
357    return sGlobalVendorTagDescriptor->getTagType(tag);
358}
359
360} /* extern "C" */
361
362} // namespace helper
363} // namespace V1_0
364} // namespace common
365} // namespace camera
366} // namespace hardware
367} // namespace android
368