diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-02-21 10:51:38 -0800 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2014-03-13 12:09:22 -0700 |
commit | d1176ef16677b6c94fb893edb6a864cdccc0b190 (patch) | |
tree | 8cc18e17c4e32633d20e8c2b7fc9e397cc1791ac /camera/VendorTagDescriptor.cpp | |
parent | 3a005b3b19b750afe24577ae322aff4602ca2740 (diff) | |
download | frameworks_av-d1176ef16677b6c94fb893edb6a864cdccc0b190.zip frameworks_av-d1176ef16677b6c94fb893edb6a864cdccc0b190.tar.gz frameworks_av-d1176ef16677b6c94fb893edb6a864cdccc0b190.tar.bz2 |
camera3: Pass vendor tags through binder.
Bug: 12134423
- Adds a class for parceling vendor tag definitions.
- Passes vendor tag definitions to clients of the camera service.
- Switches over to new vendor tag mechanism when reading from HAL.
Change-Id: Icef3fe9e67160767bdb8244ac49c85b68b497123
Diffstat (limited to 'camera/VendorTagDescriptor.cpp')
-rw-r--r-- | camera/VendorTagDescriptor.cpp | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp new file mode 100644 index 0000000..89b0ea8 --- /dev/null +++ b/camera/VendorTagDescriptor.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "VenderTagDescriptor" + +#include <binder/Parcel.h> +#include <utils/Errors.h> +#include <utils/Log.h> +#include <utils/Mutex.h> +#include <utils/Vector.h> +#include <system/camera_metadata.h> +#include <camera_metadata_hidden.h> + +#include "camera/VendorTagDescriptor.h" + +#include <string.h> + +namespace android { + +extern "C" { + +static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v); +static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray); +static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag); +static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag); +static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag); + +} /* extern "C" */ + + +static Mutex sLock; +static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor; + +VendorTagDescriptor::VendorTagDescriptor() {} +VendorTagDescriptor::~VendorTagDescriptor() {} + +status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps, + /*out*/ + sp<VendorTagDescriptor>& descriptor) { + if (vOps == NULL) { + ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__); + return BAD_VALUE; + } + + int tagCount = vOps->get_tag_count(vOps); + if (tagCount < 0 || tagCount > INT32_MAX) { + ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); + return BAD_VALUE; + } + + Vector<uint32_t> tagArray; + LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount, + "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount); + + vOps->get_all_tags(vOps, /*out*/tagArray.editArray()); + + sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); + desc->mTagCount = tagCount; + + for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) { + uint32_t tag = tagArray[i]; + if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { + ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); + return BAD_VALUE; + } + const char *tagName = vOps->get_tag_name(vOps, tag); + if (tagName == NULL) { + ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag); + return BAD_VALUE; + } + desc->mTagToNameMap.add(tag, String8(tagName)); + const char *sectionName = vOps->get_section_name(vOps, tag); + if (sectionName == NULL) { + ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag); + return BAD_VALUE; + } + desc->mTagToSectionMap.add(tag, String8(sectionName)); + int tagType = vOps->get_tag_type(vOps, tag); + if (tagType < 0 || tagType >= NUM_TYPES) { + ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); + return BAD_VALUE; + } + desc->mTagToTypeMap.add(tag, tagType); + } + descriptor = desc; + return OK; +} + +status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel, + /*out*/ + sp<VendorTagDescriptor>& descriptor) { + status_t res = OK; + if (parcel == NULL) { + ALOGE("%s: parcel argument was NULL.", __FUNCTION__); + return BAD_VALUE; + } + + int32_t tagCount = 0; + if ((res = parcel->readInt32(&tagCount)) != OK) { + ALOGE("%s: could not read tag count from parcel", __FUNCTION__); + return res; + } + + if (tagCount < 0 || tagCount > INT32_MAX) { + ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); + return BAD_VALUE; + } + + sp<VendorTagDescriptor> desc = new VendorTagDescriptor(); + desc->mTagCount = tagCount; + + uint32_t tag; + int32_t tagType; + for (int32_t i = 0; i < tagCount; ++i) { + if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) { + ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i); + break; + } + if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { + ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); + res = BAD_VALUE; + break; + } + if ((res = parcel->readInt32(&tagType)) != OK) { + ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag); + break; + } + if (tagType < 0 || tagType >= NUM_TYPES) { + ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); + res = BAD_VALUE; + break; + } + String8 tagName = parcel->readString8(); + if (tagName.isEmpty()) { + ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag); + res = NOT_ENOUGH_DATA; + break; + } + String8 sectionName = parcel->readString8(); + if (sectionName.isEmpty()) { + ALOGE("%s: parcel section name was NULL for tag %d.", __FUNCTION__, tag); + res = NOT_ENOUGH_DATA; + break; + } + + desc->mTagToNameMap.add(tag, tagName); + desc->mTagToSectionMap.add(tag, sectionName); + desc->mTagToTypeMap.add(tag, tagType); + } + + if (res != OK) { + return res; + } + + descriptor = desc; + return res; +} + +int VendorTagDescriptor::getTagCount() const { + size_t size = mTagToNameMap.size(); + if (size == 0) { + return VENDOR_TAG_COUNT_ERR; + } + return size; +} + +void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const { + size_t size = mTagToNameMap.size(); + for (size_t i = 0; i < size; ++i) { + tagArray[i] = mTagToNameMap.keyAt(i); + } +} + +const char* VendorTagDescriptor::getSectionName(uint32_t tag) const { + ssize_t index = mTagToSectionMap.indexOfKey(tag); + if (index < 0) { + return VENDOR_SECTION_NAME_ERR; + } + return mTagToSectionMap.valueAt(index).string(); +} + +const char* VendorTagDescriptor::getTagName(uint32_t tag) const { + ssize_t index = mTagToNameMap.indexOfKey(tag); + if (index < 0) { + return VENDOR_TAG_NAME_ERR; + } + return mTagToNameMap.valueAt(index).string(); +} + +int VendorTagDescriptor::getTagType(uint32_t tag) const { + ssize_t index = mTagToNameMap.indexOfKey(tag); + if (index < 0) { + return VENDOR_TAG_TYPE_ERR; + } + return mTagToTypeMap.valueFor(tag); +} + +status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const { + status_t res = OK; + if (parcel == NULL) { + ALOGE("%s: parcel argument was NULL.", __FUNCTION__); + return BAD_VALUE; + } + + if ((res = parcel->writeInt32(mTagCount)) != OK) { + return res; + } + + size_t size = mTagToNameMap.size(); + uint32_t tag; + int32_t tagType; + for (size_t i = 0; i < size; ++i) { + tag = mTagToNameMap.keyAt(i); + String8 tagName = mTagToNameMap[i]; + String8 sectionName = mTagToSectionMap.valueFor(tag); + tagType = mTagToTypeMap.valueFor(tag); + if ((res = parcel->writeInt32(tag)) != OK) break; + if ((res = parcel->writeInt32(tagType)) != OK) break; + if ((res = parcel->writeString8(tagName)) != OK) break; + if ((res = parcel->writeString8(sectionName)) != OK) break; + } + + return res; +} + +status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(sp<VendorTagDescriptor>& desc) { + status_t res = OK; + Mutex::Autolock al(sLock); + sGlobalVendorTagDescriptor = desc; + + vendor_tag_ops_t* opsPtr = NULL; + if (desc != NULL) { + opsPtr = &(desc->mVendorOps); + opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count; + opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags; + opsPtr->get_section_name = vendor_tag_descriptor_get_section_name; + opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name; + opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type; + } + if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) { + ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)." + , __FUNCTION__, strerror(-res), res); + } + return res; +} + +void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { + Mutex::Autolock al(sLock); + set_camera_metadata_vendor_ops(NULL); + sGlobalVendorTagDescriptor.clear(); +} + +sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() { + Mutex::Autolock al(sLock); + return sGlobalVendorTagDescriptor; +} + +extern "C" { + +int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v) { + Mutex::Autolock al(sLock); + if (sGlobalVendorTagDescriptor == NULL) { + ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); + return VENDOR_TAG_COUNT_ERR; + } + return sGlobalVendorTagDescriptor->getTagCount(); +} + +void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray) { + Mutex::Autolock al(sLock); + if (sGlobalVendorTagDescriptor == NULL) { + ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); + return; + } + sGlobalVendorTagDescriptor->getTagArray(tagArray); +} + +const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag) { + Mutex::Autolock al(sLock); + if (sGlobalVendorTagDescriptor == NULL) { + ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); + return VENDOR_SECTION_NAME_ERR; + } + return sGlobalVendorTagDescriptor->getSectionName(tag); +} + +const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag) { + Mutex::Autolock al(sLock); + if (sGlobalVendorTagDescriptor == NULL) { + ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); + return VENDOR_TAG_NAME_ERR; + } + return sGlobalVendorTagDescriptor->getTagName(tag); +} + +int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag) { + Mutex::Autolock al(sLock); + if (sGlobalVendorTagDescriptor == NULL) { + ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); + return VENDOR_TAG_TYPE_ERR; + } + return sGlobalVendorTagDescriptor->getTagType(tag); +} + +} /* extern "C" */ +} /* namespace android */ |