VendorTagDescriptor.cpp revision e1445da74730473a66a3ae8414e940aebfe6585d
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 "VenderTagDescriptor" 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 <system/camera_metadata.h> 25#include <camera_metadata_hidden.h> 26 27#include "camera/VendorTagDescriptor.h" 28 29#include <string.h> 30 31namespace android { 32 33extern "C" { 34 35static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v); 36static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray); 37static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag); 38static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag); 39static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag); 40 41} /* extern "C" */ 42 43 44static Mutex sLock; 45static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor; 46 47VendorTagDescriptor::VendorTagDescriptor() {} 48VendorTagDescriptor::~VendorTagDescriptor() {} 49 50status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps, 51 /*out*/ 52 sp<VendorTagDescriptor>& descriptor) { 53 if (vOps == NULL) { 54 ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__); 55 return BAD_VALUE; 56 } 57 58 int tagCount = vOps->get_tag_count(vOps); 59 if (tagCount < 0 || tagCount > INT32_MAX) { 60 ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); 61 return BAD_VALUE; 62 } 63 64 Vector<uint32_t> tagArray; 65 LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount, 66 "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount); 67 68 vOps->get_all_tags(vOps, /*out*/tagArray.editArray()); 69 70 sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); 71 desc->mTagCount = tagCount; 72 73 for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) { 74 uint32_t tag = tagArray[i]; 75 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { 76 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); 77 return BAD_VALUE; 78 } 79 const char *tagName = vOps->get_tag_name(vOps, tag); 80 if (tagName == NULL) { 81 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag); 82 return BAD_VALUE; 83 } 84 desc->mTagToNameMap.add(tag, String8(tagName)); 85 const char *sectionName = vOps->get_section_name(vOps, tag); 86 if (sectionName == NULL) { 87 ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag); 88 return BAD_VALUE; 89 } 90 desc->mTagToSectionMap.add(tag, String8(sectionName)); 91 int tagType = vOps->get_tag_type(vOps, tag); 92 if (tagType < 0 || tagType >= NUM_TYPES) { 93 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); 94 return BAD_VALUE; 95 } 96 desc->mTagToTypeMap.add(tag, tagType); 97 } 98 descriptor = desc; 99 return OK; 100} 101 102status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel, 103 /*out*/ 104 sp<VendorTagDescriptor>& descriptor) { 105 status_t res = OK; 106 if (parcel == NULL) { 107 ALOGE("%s: parcel argument was NULL.", __FUNCTION__); 108 return BAD_VALUE; 109 } 110 111 int32_t tagCount = 0; 112 if ((res = parcel->readInt32(&tagCount)) != OK) { 113 ALOGE("%s: could not read tag count from parcel", __FUNCTION__); 114 return res; 115 } 116 117 if (tagCount < 0 || tagCount > INT32_MAX) { 118 ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); 119 return BAD_VALUE; 120 } 121 122 sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); 123 desc->mTagCount = tagCount; 124 125 uint32_t tag; 126 int32_t tagType; 127 for (int32_t i = 0; i < tagCount; ++i) { 128 if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) { 129 ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i); 130 break; 131 } 132 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { 133 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); 134 res = BAD_VALUE; 135 break; 136 } 137 if ((res = parcel->readInt32(&tagType)) != OK) { 138 ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag); 139 break; 140 } 141 if (tagType < 0 || tagType >= NUM_TYPES) { 142 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); 143 res = BAD_VALUE; 144 break; 145 } 146 String8 tagName = parcel->readString8(); 147 if (tagName.isEmpty()) { 148 ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag); 149 res = NOT_ENOUGH_DATA; 150 break; 151 } 152 String8 sectionName = parcel->readString8(); 153 if (sectionName.isEmpty()) { 154 ALOGE("%s: parcel section name was NULL for tag %d.", __FUNCTION__, tag); 155 res = NOT_ENOUGH_DATA; 156 break; 157 } 158 159 desc->mTagToNameMap.add(tag, tagName); 160 desc->mTagToSectionMap.add(tag, sectionName); 161 desc->mTagToTypeMap.add(tag, tagType); 162 } 163 164 if (res != OK) { 165 return res; 166 } 167 168 descriptor = desc; 169 return res; 170} 171 172int VendorTagDescriptor::getTagCount() const { 173 size_t size = mTagToNameMap.size(); 174 if (size == 0) { 175 return VENDOR_TAG_COUNT_ERR; 176 } 177 return size; 178} 179 180void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const { 181 size_t size = mTagToNameMap.size(); 182 for (size_t i = 0; i < size; ++i) { 183 tagArray[i] = mTagToNameMap.keyAt(i); 184 } 185} 186 187const char* VendorTagDescriptor::getSectionName(uint32_t tag) const { 188 ssize_t index = mTagToSectionMap.indexOfKey(tag); 189 if (index < 0) { 190 return VENDOR_SECTION_NAME_ERR; 191 } 192 return mTagToSectionMap.valueAt(index).string(); 193} 194 195const char* VendorTagDescriptor::getTagName(uint32_t tag) const { 196 ssize_t index = mTagToNameMap.indexOfKey(tag); 197 if (index < 0) { 198 return VENDOR_TAG_NAME_ERR; 199 } 200 return mTagToNameMap.valueAt(index).string(); 201} 202 203int VendorTagDescriptor::getTagType(uint32_t tag) const { 204 ssize_t index = mTagToNameMap.indexOfKey(tag); 205 if (index < 0) { 206 return VENDOR_TAG_TYPE_ERR; 207 } 208 return mTagToTypeMap.valueFor(tag); 209} 210 211status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const { 212 status_t res = OK; 213 if (parcel == NULL) { 214 ALOGE("%s: parcel argument was NULL.", __FUNCTION__); 215 return BAD_VALUE; 216 } 217 218 if ((res = parcel->writeInt32(mTagCount)) != OK) { 219 return res; 220 } 221 222 size_t size = mTagToNameMap.size(); 223 uint32_t tag; 224 int32_t tagType; 225 for (size_t i = 0; i < size; ++i) { 226 tag = mTagToNameMap.keyAt(i); 227 String8 tagName = mTagToNameMap[i]; 228 String8 sectionName = mTagToSectionMap.valueFor(tag); 229 tagType = mTagToTypeMap.valueFor(tag); 230 if ((res = parcel->writeInt32(tag)) != OK) break; 231 if ((res = parcel->writeInt32(tagType)) != OK) break; 232 if ((res = parcel->writeString8(tagName)) != OK) break; 233 if ((res = parcel->writeString8(sectionName)) != OK) break; 234 } 235 236 return res; 237} 238 239status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) { 240 status_t res = OK; 241 Mutex::Autolock al(sLock); 242 sGlobalVendorTagDescriptor = desc; 243 244 vendor_tag_ops_t* opsPtr = NULL; 245 if (desc != NULL) { 246 opsPtr = &(desc->mVendorOps); 247 opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count; 248 opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags; 249 opsPtr->get_section_name = vendor_tag_descriptor_get_section_name; 250 opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name; 251 opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type; 252 } 253 if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) { 254 ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)." 255 , __FUNCTION__, strerror(-res), res); 256 } 257 return res; 258} 259 260void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { 261 Mutex::Autolock al(sLock); 262 set_camera_metadata_vendor_ops(NULL); 263 sGlobalVendorTagDescriptor.clear(); 264} 265 266sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() { 267 Mutex::Autolock al(sLock); 268 return sGlobalVendorTagDescriptor; 269} 270 271extern "C" { 272 273int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v) { 274 Mutex::Autolock al(sLock); 275 if (sGlobalVendorTagDescriptor == NULL) { 276 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); 277 return VENDOR_TAG_COUNT_ERR; 278 } 279 return sGlobalVendorTagDescriptor->getTagCount(); 280} 281 282void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray) { 283 Mutex::Autolock al(sLock); 284 if (sGlobalVendorTagDescriptor == NULL) { 285 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); 286 return; 287 } 288 sGlobalVendorTagDescriptor->getTagArray(tagArray); 289} 290 291const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag) { 292 Mutex::Autolock al(sLock); 293 if (sGlobalVendorTagDescriptor == NULL) { 294 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); 295 return VENDOR_SECTION_NAME_ERR; 296 } 297 return sGlobalVendorTagDescriptor->getSectionName(tag); 298} 299 300const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag) { 301 Mutex::Autolock al(sLock); 302 if (sGlobalVendorTagDescriptor == NULL) { 303 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); 304 return VENDOR_TAG_NAME_ERR; 305 } 306 return sGlobalVendorTagDescriptor->getTagName(tag); 307} 308 309int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag) { 310 Mutex::Autolock al(sLock); 311 if (sGlobalVendorTagDescriptor == NULL) { 312 ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); 313 return VENDOR_TAG_TYPE_ERR; 314 } 315 return sGlobalVendorTagDescriptor->getTagType(tag); 316} 317 318} /* extern "C" */ 319} /* namespace android */ 320