VendorTagDescriptor.cpp revision 0c629a3857c31bee6fa39ba7a9a8cbcabeb383fd
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 33namespace android { 34 35extern "C" { 36 37static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v); 38static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray); 39static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag); 40static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag); 41static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag); 42 43} /* extern "C" */ 44 45 46static Mutex sLock; 47static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor; 48 49VendorTagDescriptor::VendorTagDescriptor() {} 50 51VendorTagDescriptor::~VendorTagDescriptor() { 52 size_t len = mReverseMapping.size(); 53 for (size_t i = 0; i < len; ++i) { 54 delete mReverseMapping[i]; 55 } 56} 57 58status_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 139status_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 252int 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 260void 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 267const 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 275const 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 283int 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 291status_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 327SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const { 328 return mSections; 329} 330 331status_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 350void 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 380status_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 401void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { 402 Mutex::Autolock al(sLock); 403 set_camera_metadata_vendor_ops(NULL); 404 sGlobalVendorTagDescriptor.clear(); 405} 406 407sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() { 408 Mutex::Autolock al(sLock); 409 return sGlobalVendorTagDescriptor; 410} 411 412extern "C" { 413 414int 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 423void 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 432const 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 441const 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 450int 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