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
33 namespace android {
34
35 extern "C" {
36
37 static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
38 static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
39 static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
40 static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
41 static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
42
43 } /* extern "C" */
44
45
46 static Mutex sLock;
47 static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
48
VendorTagDescriptor()49 VendorTagDescriptor::VendorTagDescriptor() {}
50
~VendorTagDescriptor()51 VendorTagDescriptor::~VendorTagDescriptor() {
52 size_t len = mReverseMapping.size();
53 for (size_t i = 0; i < len; ++i) {
54 delete mReverseMapping[i];
55 }
56 }
57
createDescriptorFromOps(const vendor_tag_ops_t * vOps,sp<VendorTagDescriptor> & descriptor)58 status_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
createFromParcel(const Parcel * parcel,sp<VendorTagDescriptor> & descriptor)139 status_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*>(§ionIndex))) != 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*>(§ionCount))) != 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
getTagCount() const252 int 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
getTagArray(uint32_t * tagArray) const260 void 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
getSectionName(uint32_t tag) const267 const 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
getTagName(uint32_t tag) const275 const 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
getTagType(uint32_t tag) const283 int 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
writeToParcel(Parcel * parcel) const291 status_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
getAllSectionNames() const327 SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
328 return mSections;
329 }
330
lookupTag(String8 name,String8 section,uint32_t * tag) const331 status_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
dump(int fd,int verbosity,int indentation) const350 void 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
setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor> & desc)380 status_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
clearGlobalVendorTagDescriptor()401 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
402 Mutex::Autolock al(sLock);
403 set_camera_metadata_vendor_ops(NULL);
404 sGlobalVendorTagDescriptor.clear();
405 }
406
getGlobalVendorTagDescriptor()407 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
408 Mutex::Autolock al(sLock);
409 return sGlobalVendorTagDescriptor;
410 }
411
412 extern "C" {
413
vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t *)414 int 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
vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t *,uint32_t * tagArray)423 void 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
vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t *,uint32_t tag)432 const 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
vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t *,uint32_t tag)441 const 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
vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t *,uint32_t tag)450 int 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