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 VendorTagDescriptor::VendorTagDescriptor() {}
     50 
     51 VendorTagDescriptor::~VendorTagDescriptor() {
     52     size_t len = mReverseMapping.size();
     53     for (size_t i = 0; i < len; ++i)  {
     54         delete mReverseMapping[i];
     55     }
     56 }
     57 
     58 status_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 
    139 status_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*>(&sectionIndex))) != 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;
    210     if (tagCount > 0) {
    211         if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionCount))) != 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 
    252 int 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 
    260 void 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 
    267 const 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 
    275 const 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 
    283 int 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 
    291 status_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 
    327 SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
    328     return mSections;
    329 }
    330 
    331 status_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 
    350 void 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 
    380 status_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 
    401 void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
    402     Mutex::Autolock al(sLock);
    403     set_camera_metadata_vendor_ops(NULL);
    404     sGlobalVendorTagDescriptor.clear();
    405 }
    406 
    407 sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
    408     Mutex::Autolock al(sLock);
    409     return sGlobalVendorTagDescriptor;
    410 }
    411 
    412 extern "C" {
    413 
    414 int 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 
    423 void 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 
    432 const 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 
    441 const 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 
    450 int 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