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     ssize_t index = mTagToNameMap.indexOfKey(tag);
120     if (index < 0) {
121         return VENDOR_TAG_TYPE_ERR;
122     }
123     return mTagToTypeMap.valueFor(tag);
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.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 
182 namespace camera {
183 namespace common {
184 namespace V1_0 {
185 namespace helper {
186 
187 extern "C" {
188 
189 static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
190 static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
191 static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
192 static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
193 static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
194 
195 } /* extern "C" */
196 
197 static Mutex sLock;
198 static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
199 
createDescriptorFromOps(const vendor_tag_ops_t * vOps,sp<VendorTagDescriptor> & descriptor)200 status_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 
setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor> & desc)281 status_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 
clearGlobalVendorTagDescriptor()302 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
303     Mutex::Autolock al(sLock);
304     set_camera_metadata_vendor_ops(NULL);
305     sGlobalVendorTagDescriptor.clear();
306 }
307 
getGlobalVendorTagDescriptor()308 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
309     Mutex::Autolock al(sLock);
310     return sGlobalVendorTagDescriptor;
311 }
312 
313 extern "C" {
314 
vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t *)315 int 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 
vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t *,uint32_t * tagArray)324 void 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 
vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t *,uint32_t tag)333 const 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 
vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t *,uint32_t tag)342 const 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 
vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t *,uint32_t tag)351 int 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