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
49 namespace hardware {
50 namespace camera2 {
51 namespace params {
52
~VendorTagDescriptor()53 VendorTagDescriptor::~VendorTagDescriptor() {
54 size_t len = mReverseMapping.size();
55 for (size_t i = 0; i < len; ++i) {
56 delete mReverseMapping[i];
57 }
58 }
59
VendorTagDescriptor()60 VendorTagDescriptor::VendorTagDescriptor() :
61 mTagCount(0),
62 mVendorOps() {
63 }
64
VendorTagDescriptor(const VendorTagDescriptor & src)65 VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
66 copyFrom(src);
67 }
68
operator =(const VendorTagDescriptor & rhs)69 VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
70 copyFrom(rhs);
71 return *this;
72 }
73
copyFrom(const VendorTagDescriptor & src)74 void 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
readFromParcel(const Parcel * parcel)99 status_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*>(§ionIndex))) != 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*>(§ionCount))) != 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
getTagCount() const208 int 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
getTagArray(uint32_t * tagArray) const216 void 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
getSectionName(uint32_t tag) const223 const 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
getTagName(uint32_t tag) const231 const 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
getTagType(uint32_t tag) const239 int 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
writeToParcel(Parcel * parcel) const247 status_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
getAllSectionNames() const283 SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
284 return mSections;
285 }
286
lookupTag(String8 name,String8 section,uint32_t * tag) const287 status_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
dump(int fd,int verbosity,int indentation) const306 void 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
createDescriptorFromOps(const vendor_tag_ops_t * vOps,sp<VendorTagDescriptor> & descriptor)341 status_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
setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor> & desc)422 status_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
clearGlobalVendorTagDescriptor()443 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
444 Mutex::Autolock al(sLock);
445 set_camera_metadata_vendor_ops(NULL);
446 sGlobalVendorTagDescriptor.clear();
447 }
448
getGlobalVendorTagDescriptor()449 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
450 Mutex::Autolock al(sLock);
451 return sGlobalVendorTagDescriptor;
452 }
453
454 extern "C" {
455
vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t *)456 int 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
vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t *,uint32_t * tagArray)465 void 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
vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t *,uint32_t tag)474 const 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
vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t *,uint32_t tag)483 const 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
vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t *,uint32_t tag)492 int 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