Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71c73a29 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Support vendor tags from multiple providers

Different vendors could have different vendor tags.
A global vendor tag cache will store all available
vendor tag descriptors from different providers.
The cache will then be shared with each camera client.
Camera metadata will use specific vendor ids stored
in the metadata buffer to identify the correct vendor
tag provider.

Bug: 34275821
Test: adb shell /data/nativetest/cameraservice_test/cameraservice_test
--gtest_filter=CameraProviderManagerTest.MultipleVendorTagTest
Complete Camera/Camera2 CTS tests
Change-Id: I2262128f21a0167504f018230624e2a89786c467
parent 98e11c12
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ status_t CameraMetadata::sort() {
}

status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
    int tagType = get_camera_metadata_tag_type(tag);
    int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
    if ( CC_UNLIKELY(tagType == -1)) {
        ALOGE("Update metadata entry: Unknown tag %d", tag);
        return INVALID_OPERATION;
@@ -178,7 +178,7 @@ status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
    if ( CC_UNLIKELY(tagType != expectedType) ) {
        ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
                "got type %s data instead ",
                get_camera_metadata_tag_name(tag), tag,
                get_local_camera_metadata_tag_name(tag, mBuffer), tag,
                camera_metadata_type_names[tagType],
                camera_metadata_type_names[expectedType]);
        return INVALID_OPERATION;
@@ -297,7 +297,7 @@ status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
        return INVALID_OPERATION;
    }
    int type = get_camera_metadata_tag_type(tag);
    int type = get_local_camera_metadata_tag_type(tag, mBuffer);
    if (type == -1) {
        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
        return BAD_VALUE;
@@ -332,8 +332,9 @@ status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,

    if (res != OK) {
        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
                __FUNCTION__, get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
                __FUNCTION__, get_local_camera_metadata_section_name(tag, mBuffer),
                get_local_camera_metadata_tag_name(tag, mBuffer), tag,
                strerror(-res), res);
    }

    IF_ALOGV() {
@@ -392,16 +393,18 @@ status_t CameraMetadata::erase(uint32_t tag) {
    } else if (res != OK) {
        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
                __FUNCTION__,
                get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
                get_local_camera_metadata_section_name(tag, mBuffer),
                get_local_camera_metadata_tag_name(tag, mBuffer),
                tag, strerror(-res), res);
        return res;
    }
    res = delete_camera_metadata_entry(mBuffer, entry.index);
    if (res != OK) {
        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
                __FUNCTION__,
                get_camera_metadata_section_name(tag),
                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
                get_local_camera_metadata_section_name(tag, mBuffer),
                get_local_camera_metadata_tag_name(tag, mBuffer),
                tag, strerror(-res), res);
    }
    return res;
}
+249 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

#include <stdio.h>
#include <string.h>
#include <inttypes.h>

namespace android {

@@ -40,11 +41,22 @@ static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t
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);

static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray,
        metadata_vendor_id_t id);
static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
        metadata_vendor_id_t id);
static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag,
        metadata_vendor_id_t id);
static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag,
        metadata_vendor_id_t id);

} /* extern "C" */


static Mutex sLock;
static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;

namespace hardware {
namespace camera2 {
@@ -333,11 +345,166 @@ void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {

}

status_t VendorTagDescriptorCache::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(mVendorMap.size())) != OK) {
        return res;
    }

    for (const auto &iter : mVendorMap) {
        if ((res = parcel->writeUint64(iter.first)) != OK) break;
        if ((res = parcel->writeParcelable(*iter.second)) != OK) break;
    }

    return res;
}


status_t VendorTagDescriptorCache::readFromParcel(const Parcel* parcel) {
    status_t res = OK;
    if (parcel == NULL) {
        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
        return BAD_VALUE;
    }

    int32_t vendorCount = 0;
    if ((res = parcel->readInt32(&vendorCount)) != OK) {
        ALOGE("%s: could not read vendor count from parcel", __FUNCTION__);
        return res;
    }

    if (vendorCount < 0 || vendorCount > INT32_MAX) {
        ALOGE("%s: vendor count %d from is invalid.", __FUNCTION__, vendorCount);
        return BAD_VALUE;
    }

    metadata_vendor_id_t id;
    for (int32_t i = 0; i < vendorCount; i++) {
        if ((res = parcel->readUint64(&id)) != OK) {
            ALOGE("%s: could not read vendor id from parcel for index %d",
                  __FUNCTION__, i);
            break;
        }
        sp<android::VendorTagDescriptor> desc = new android::VendorTagDescriptor();
        if ((res = parcel->readParcelable(desc.get())) != OK) {
            ALOGE("%s: could not read vendor tag descriptor from parcel for index %d rc = %d",
                  __FUNCTION__, i, res);
            break;
        }

        if ((res = addVendorDescriptor(id, desc)) != OK) {
            ALOGE("%s: failed to add vendor tag descriptor for index: %d ",
                  __FUNCTION__, i);
            break;
        }
    }

    return res;
}

int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
    int ret = 0;
    auto desc = mVendorMap.find(id);
    if (desc != mVendorMap.end()) {
        ret = desc->second->getTagCount();
    } else {
        ALOGE("%s: Vendor descriptor id is missing!", __func__);
    }

    return ret;
}

void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray,
        metadata_vendor_id_t id) const {
    auto desc = mVendorMap.find(id);
    if (desc != mVendorMap.end()) {
        desc->second->getTagArray(tagArray);
    } else {
        ALOGE("%s: Vendor descriptor id is missing!", __func__);
    }
}

const char* VendorTagDescriptorCache::getSectionName(uint32_t tag,
        metadata_vendor_id_t id) const {
    const char *ret = nullptr;
    auto desc = mVendorMap.find(id);
    if (desc != mVendorMap.end()) {
        ret = desc->second->getSectionName(tag);
    } else {
        ALOGE("%s: Vendor descriptor id is missing!", __func__);
    }

    return ret;
}

const char* VendorTagDescriptorCache::getTagName(uint32_t tag,
        metadata_vendor_id_t id) const {
    const char *ret = nullptr;
    auto desc = mVendorMap.find(id);
    if (desc != mVendorMap.end()) {
        ret = desc->second->getTagName(tag);
    } else {
        ALOGE("%s: Vendor descriptor id is missing!", __func__);
    }

    return ret;
}

int VendorTagDescriptorCache::getTagType(uint32_t tag,
        metadata_vendor_id_t id) const {
    int ret = 0;
    auto desc = mVendorMap.find(id);
    if (desc != mVendorMap.end()) {
        ret = desc->second->getTagType(tag);
    } else {
        ALOGE("%s: Vendor descriptor id is missing!", __func__);
    }

    return ret;
}

void VendorTagDescriptorCache::dump(int fd, int verbosity,
        int indentation) const {
    for (const auto &desc : mVendorMap) {
        dprintf(fd, "%*sDumping vendor tag descriptors for vendor with"
                " id %" PRIu64 " \n", indentation, "", desc.first);
        desc.second->dump(fd, verbosity, indentation);
    }
}

int32_t VendorTagDescriptorCache::addVendorDescriptor(metadata_vendor_id_t id,
        sp<android::VendorTagDescriptor> desc) {
    auto entry = mVendorMap.find(id);
    if (entry != mVendorMap.end()) {
        ALOGE("%s: Vendor descriptor with same id already present!", __func__);
        return BAD_VALUE;
    }

    mVendorMap.emplace(id, desc);
    return NO_ERROR;
}

int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
        metadata_vendor_id_t id, sp<android::VendorTagDescriptor> *desc /*out*/) {
    auto entry = mVendorMap.find(id);
    if (entry == mVendorMap.end()) {
        return NAME_NOT_FOUND;
    }

    *desc = entry->second;

    return NO_ERROR;
}

} // namespace params
} // namespace camera2
} // namespace hardware


status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
            /*out*/
            sp<VendorTagDescriptor>& descriptor) {
@@ -451,6 +618,39 @@ sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
    return sGlobalVendorTagDescriptor;
}

status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
        const sp<VendorTagDescriptorCache>& cache) {
    status_t res = OK;
    Mutex::Autolock al(sLock);
    sGlobalVendorTagDescriptorCache = cache;

    struct vendor_tag_cache_ops* opsPtr = NULL;
    if (cache != NULL) {
        opsPtr = &(cache->mVendorCacheOps);
        opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
        opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
        opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
        opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
        opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
    }
    if((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
        ALOGE("%s: Could not set vendor tag cache, received error %s (%d)."
                , __FUNCTION__, strerror(-res), res);
    }
    return res;
}

void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
    Mutex::Autolock al(sLock);
    set_camera_metadata_vendor_cache_ops(NULL);
    sGlobalVendorTagDescriptorCache.clear();
}

sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
    Mutex::Autolock al(sLock);
    return sGlobalVendorTagDescriptorCache;
}

extern "C" {

int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
@@ -498,5 +698,53 @@ int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t t
    return sGlobalVendorTagDescriptor->getTagType(tag);
}

int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
    Mutex::Autolock al(sLock);
    if (sGlobalVendorTagDescriptorCache == NULL) {
        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
        return VENDOR_TAG_COUNT_ERR;
    }
    return sGlobalVendorTagDescriptorCache->getTagCount(id);
}

void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray,
        metadata_vendor_id_t id) {
    Mutex::Autolock al(sLock);
    if (sGlobalVendorTagDescriptorCache == NULL) {
        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
    }
    sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
}

const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
        metadata_vendor_id_t id) {
    Mutex::Autolock al(sLock);
    if (sGlobalVendorTagDescriptorCache == NULL) {
        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
        return VENDOR_SECTION_NAME_ERR;
    }
    return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
}

const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag,
        metadata_vendor_id_t id) {
    Mutex::Autolock al(sLock);
    if (sGlobalVendorTagDescriptorCache == NULL) {
        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
        return VENDOR_TAG_NAME_ERR;
    }
    return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
}

int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag,
        metadata_vendor_id_t id) {
    Mutex::Autolock al(sLock);
    if (sGlobalVendorTagDescriptorCache == NULL) {
        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
        return VENDOR_TAG_NAME_ERR;
    }
    return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
}

} /* extern "C" */
} /* namespace android */
+9 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.hardware.ICameraClient;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.params.VendorTagDescriptor;
import android.hardware.camera2.params.VendorTagDescriptorCache;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.ICameraServiceListener;
import android.hardware.CameraInfo;
@@ -129,6 +130,14 @@ interface ICameraService
     */
    VendorTagDescriptor getCameraVendorTagDescriptor();

    /**
     * Retrieve the vendor tag descriptor cache which can have multiple vendor
     * providers.
     * Intended to be used by the native code of CameraMetadataNative to correctly
     * interpret camera metadata with vendor tags.
     */
    VendorTagDescriptorCache getCameraVendorTagCache();

    /**
     * Read the legacy camera1 parameters into a String
     */
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

package android.hardware.camera2.params;

/** @hide */
parcelable VendorTagDescriptorCache cpp_header "camera/VendorTagDescriptor.h";
+78 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
#include <utils/String8.h>
#include <utils/RefBase.h>
#include <system/camera_vendor_tags.h>

#include <unordered_map>
#include <stdint.h>

namespace android {
@@ -166,8 +166,84 @@ class VendorTagDescriptor :

};

} /* namespace android */
namespace hardware {
namespace camera2 {
namespace params {

class VendorTagDescriptorCache : public Parcelable {
  public:

    VendorTagDescriptorCache() {};

    int32_t addVendorDescriptor(metadata_vendor_id_t id,
            sp<android::VendorTagDescriptor> desc);

    int32_t getVendorTagDescriptor(
            metadata_vendor_id_t id,
            sp<android::VendorTagDescriptor> *desc /*out*/);

    // Parcelable interface
    status_t writeToParcel(Parcel* parcel) const override;
    status_t readFromParcel(const Parcel* parcel) override;

    // Returns the number of vendor tags defined.
    int getTagCount(metadata_vendor_id_t id) const;

    // Returns an array containing the id's of vendor tags defined.
    void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;

    // Returns the section name string for a given vendor tag id.
    const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;

    // Returns the tag name string for a given vendor tag id.
    const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;

    // Returns the tag type for a given vendor tag id.
    int getTagType(uint32_t tag, metadata_vendor_id_t id) const;

    /**
     * Dump the currently configured vendor tags to a file descriptor.
     */
    void dump(int fd, int verbosity, int indentation) const;

  protected:
    std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>> mVendorMap;
    struct vendor_tag_cache_ops mVendorCacheOps;
};

} /* namespace params */
} /* namespace camera2 */
} /* namespace hardware */

class VendorTagDescriptorCache :
        public ::android::hardware::camera2::params::VendorTagDescriptorCache,
        public LightRefBase<VendorTagDescriptorCache> {
  public:

    /**
     * Sets the global vendor tag descriptor cache to use for this process.
     * Camera metadata operations that access vendor tags will use the
     * vendor tag definitions set this way.
     *
     * Returns OK on success, or a negative error code.
     */
    static status_t setAsGlobalVendorTagCache(
            const sp<VendorTagDescriptorCache>& cache);

    /**
     * Returns the global vendor tag cache used by this process.
     * This will contain NULL if no vendor tags are defined.
     */
    static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();

    /**
     * Clears the global vendor tag cache used by this process.
     */
    static void clearGlobalVendorTagCache();

};

} /* namespace android */

#define VENDOR_TAG_DESCRIPTOR_H
#endif /* VENDOR_TAG_DESCRIPTOR_H */
Loading