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