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 49namespace hardware { 50namespace camera2 { 51namespace params { 52 53VendorTagDescriptor::~VendorTagDescriptor() { 54 size_t len = mReverseMapping.size(); 55 for (size_t i = 0; i < len; ++i) { 56 delete mReverseMapping[i]; 57 } 58} 59 60VendorTagDescriptor::VendorTagDescriptor() : 61 mTagCount(0), 62 mVendorOps() { 63} 64 65VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) { 66 copyFrom(src); 67} 68 69VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) { 70 copyFrom(rhs); 71 return *this; 72} 73 74void 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 99status_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 208int 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 216void 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 223const 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 231const 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 239int 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 247status_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 283SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const { 284 return mSections; 285} 286 287status_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 306void 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 341status_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 422status_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 443void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { 444 Mutex::Autolock al(sLock); 445 set_camera_metadata_vendor_ops(NULL); 446 sGlobalVendorTagDescriptor.clear(); 447} 448 449sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() { 450 Mutex::Autolock al(sLock); 451 return sGlobalVendorTagDescriptor; 452} 453 454extern "C" { 455 456int 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 465void 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 474const 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 483const 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 492int 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