Home | History | Annotate | Download | only in camera
      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 
     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 
     60 VendorTagDescriptor::VendorTagDescriptor() :
     61         mTagCount(0),
     62         mVendorOps() {
     63 }
     64 
     65 VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
     66     copyFrom(src);
     67 }
     68 
     69 VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
     70     copyFrom(rhs);
     71     return *this;
     72 }
     73 
     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 
     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*>(&sectionIndex))) != 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*>(&sectionCount))) != 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 
    208 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 
    216 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 
    223 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 
    231 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 
    239 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 
    247 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 
    283 SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
    284     return mSections;
    285 }
    286 
    287 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 
    306 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 
    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 
    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 
    443 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
    444     Mutex::Autolock al(sLock);
    445     set_camera_metadata_vendor_ops(NULL);
    446     sGlobalVendorTagDescriptor.clear();
    447 }
    448 
    449 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
    450     Mutex::Autolock al(sLock);
    451     return sGlobalVendorTagDescriptor;
    452 }
    453 
    454 extern "C" {
    455 
    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 
    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 
    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 
    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 
    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