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 32namespace android { 33namespace hardware { 34namespace camera2 { 35namespace params { 36 37VendorTagDescriptor::~VendorTagDescriptor() { 38 size_t len = mReverseMapping.size(); 39 for (size_t i = 0; i < len; ++i) { 40 delete mReverseMapping[i]; 41 } 42} 43 44VendorTagDescriptor::VendorTagDescriptor() : 45 mTagCount(0), 46 mVendorOps() { 47} 48 49VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) { 50 copyFrom(src); 51} 52 53VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) { 54 copyFrom(rhs); 55 return *this; 56} 57 58void 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 83int 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 91void 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 98const 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 106ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const { 107 return mTagToSectionMap.valueFor(tag); 108} 109 110const 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 118int 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 126const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const { 127 return &mSections; 128} 129 130status_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 149void 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 182namespace camera { 183namespace common { 184namespace V1_0 { 185namespace helper { 186 187extern "C" { 188 189static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v); 190static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray); 191static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag); 192static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag); 193static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag); 194 195} /* extern "C" */ 196 197static Mutex sLock; 198static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor; 199 200status_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 281status_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 302void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { 303 Mutex::Autolock al(sLock); 304 set_camera_metadata_vendor_ops(NULL); 305 sGlobalVendorTagDescriptor.clear(); 306} 307 308sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() { 309 Mutex::Autolock al(sLock); 310 return sGlobalVendorTagDescriptor; 311} 312 313extern "C" { 314 315int 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 324void 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 333const 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 342const 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 351int 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