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

Commit f3a8a239 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh Committed by Android (Google) Code Review
Browse files

Merge changes from topics 'cam-hidl-fence', 'camera-hidl-bufId'

* changes:
  Camera: wait for remote camera provider
  Camera: setup vendor tag in binderized mode
  Camera: treble: close acquire_fence
  Camera: pass bufferId to HIDL interface
parents 17bd3ded 6540509f
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -324,7 +324,10 @@ status_t CameraService::enumerateProviders() {
    mNumberOfCameras = mCameraProviderManager->getCameraCount();
    mNumberOfNormalCameras = mCameraProviderManager->getStandardCameraCount();

    // TODO: Set up vendor tags
    // Setup vendor tags before we call get_camera_info the first time
    // because HAL might need to setup static vendor keys in get_camera_info
    // TODO: maybe put this into CameraProviderManager::initialize()?
    mCameraProviderManager->setUpVendorTags();

    mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
    res = mFlashlight->findFlashUnits();
+163 −18
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include "CameraProviderManager.h"

#include <chrono>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>

@@ -46,6 +47,8 @@ CameraProviderManager::~CameraProviderManager() {

status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) {
    int numProviders = 0;
    {
        std::lock_guard<std::mutex> lock(mInterfaceMutex);
        if (proxy == nullptr) {
            ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
@@ -63,9 +66,23 @@ status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListe
                    "about camera providers", __FUNCTION__);
            return INVALID_OPERATION;
        }
        numProviders = mProviders.size();
    }

    // Also see if there's a passthrough HAL, but let's not complain if there's not
    if (numProviders == 0) {
        // Remote provider might have not been initialized
        // Wait for a bit and see if we get one registered
        std::mutex mtx;
        std::unique_lock<std::mutex> lock(mtx);
        mProviderRegistered.wait_for(lock, std::chrono::seconds(15));
        if (mProviders.size() == 0) {
            ALOGI("%s: Unable to get one registered provider within timeout!",
                    __FUNCTION__);
            std::lock_guard<std::mutex> lock(mInterfaceMutex);
            // See if there's a passthrough HAL, but let's not complain if there's not
            addProvider(kLegacyProviderName, /*expected*/ false);
        }
    }

    return OK;
}
@@ -189,6 +206,42 @@ status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled
    return deviceInfo->setTorchMode(enabled);
}

status_t CameraProviderManager::setUpVendorTags() {
    // TODO (b/34275821): support aggregating vendor tags for more than one provider
    for (auto& provider : mProviders) {
        hardware::hidl_vec<VendorTagSection> vts;
        Status status;
        provider->mInterface->getVendorTags(
            [&](auto s, const auto& vendorTagSecs) {
                status = s;
                if (s == Status::OK) {
                    vts = vendorTagSecs;
                }
        });

        if (status != Status::OK) {
            return mapToStatusT(status);
        }

        VendorTagDescriptor::clearGlobalVendorTagDescriptor();

        // Read all vendor tag definitions into a descriptor
        sp<VendorTagDescriptor> desc;
        status_t res;
        if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
                != OK) {
            ALOGE("%s: Could not generate descriptor from vendor tag operations,"
                  "received error %s (%d). Camera clients will not be able to use"
                  "vendor tags", __FUNCTION__, strerror(res), res);
            return res;
        }

        // Set the global descriptor to use with camera metadata
        VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
    }
    return OK;
}

status_t CameraProviderManager::openSession(const std::string &id,
        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
        /*out*/
@@ -241,6 +294,7 @@ hardware::Return<void> CameraProviderManager::onRegistration(
    std::lock_guard<std::mutex> lock(mInterfaceMutex);

    addProvider(name);
    mProviderRegistered.notify_one();
    return hardware::Return<void>();
}

@@ -334,7 +388,8 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
        return BAD_VALUE;
    }
    ALOGI("Connecting to new camera provider: %s", mProviderName.c_str());
    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
            mProviderName.c_str(), mInterface->isRemote());
    Status status = mInterface->setCallback(this);
    if (status != Status::OK) {
        ALOGE("%s: Unable to register callbacks with camera provider '%s'",
@@ -971,4 +1026,94 @@ const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s)
    return "UNKNOWN_STATUS";
}


status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
        const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
        /*out*/
        sp<VendorTagDescriptor>& descriptor) {

    int tagCount = 0;

    for (size_t s = 0; s < vts.size(); s++) {
        tagCount += vts[s].tags.size();
    }

    if (tagCount < 0 || tagCount > INT32_MAX) {
        ALOGE("%s: tag count %d from vendor tag sections 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);


    sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
    desc->mTagCount = tagCount;

    SortedVector<String8> sections;
    KeyedVector<uint32_t, String8> tagToSectionMap;

    int idx = 0;
    for (size_t s = 0; s < vts.size(); s++) {
        const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
        const char *sectionName = section.sectionName.c_str();
        if (sectionName == NULL) {
            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
            return BAD_VALUE;
        }
        String8 sectionString(sectionName);
        sections.add(sectionString);

        for (size_t j = 0; j < section.tags.size(); j++) {
            uint32_t tag = section.tags[j].tagId;
            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
                return BAD_VALUE;
            }

            tagArray.editItemAt(idx++) = section.tags[j].tagId;

            const char *tagName = section.tags[j].tagName.c_str();
            if (tagName == NULL) {
                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
                return BAD_VALUE;
            }
            desc->mTagToNameMap.add(tag, String8(tagName));
            tagToSectionMap.add(tag, sectionString);

            int tagType = (int) section.tags[j].tagType;
            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);
        }
    }

    desc->mSections = sections;

    for (size_t i = 0; i < tagArray.size(); ++i) {
        uint32_t tag = tagArray[i];
        String8 sectionString = tagToSectionMap.valueFor(tag);

        // Set up tag to section index map
        ssize_t index = sections.indexOf(sectionString);
        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));

        // Set up reverse mapping
        ssize_t reverseIndex = -1;
        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
        }
        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
    }

    descriptor = desc;
    return OK;
}


} // namespace android
+28 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <vector>
#include <string>
#include <mutex>
#include <condition_variable>

#include <camera/CameraParameters2.h>
#include <camera/CameraMetadata.h>
@@ -29,9 +30,29 @@
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
//#include <android/hardware/camera/provider/2.4/ICameraProviderCallbacks.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include <camera/VendorTagDescriptor.h>

namespace android {

/**
 * The vendor tag descriptor class that takes HIDL vendor tag information as
 * input. Not part of VendorTagDescriptor class because that class is used
 * in AIDL generated sources which don't have access to HIDL headers.
 */
class HidlVendorTagDescriptor : public VendorTagDescriptor {
public:
    /**
     * Create a VendorTagDescriptor object from the HIDL VendorTagSection
     * vector.
     *
     * Returns OK on success, or a negative error code.
     */
    static status_t createDescriptorFromHidl(
            const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
            /*out*/
            sp<VendorTagDescriptor>& descriptor);
};

/**
 * A manager for all camera providers available on an Android device.
 *
@@ -155,6 +176,11 @@ public:
     */
    status_t setTorchMode(const std::string &id, bool enabled);

    /**
     * Setup vendor tags for all registered providers
     */
    status_t setUpVendorTags();

    /**
     * Open an active session to a camera device.
     *
@@ -194,6 +220,8 @@ private:
    // All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
    mutable std::mutex mInterfaceMutex;

    std::condition_variable mProviderRegistered;

    // the status listener update callbacks will lock mStatusMutex
    mutable std::mutex mStatusListenerMutex;
    wp<StatusListener> mListener;
+61 −11
Original line number Diff line number Diff line
@@ -955,8 +955,7 @@ hardware::Return<void> Camera3Device::processCaptureResult(
        bDst.stream = mOutputStreams.valueAt(idx)->asHalStream();

        buffer_handle_t *buffer;
        res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId,
                &buffer);
        res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
        if (res != OK) {
            ALOGE("%s: Frame %d: Buffer %zu: No in-flight buffer for stream %d",
                    __FUNCTION__, result.frameNumber, i, bSrc.streamId);
@@ -3184,7 +3183,7 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
        res = mHal3Device->ops->configure_streams(mHal3Device, config);
    } else {
        // Convert stream config to HIDL

        std::set<int> activeStreams;
        StreamConfiguration requestedConfiguration;
        requestedConfiguration.streams.resize(config->num_streams);
        for (size_t i = 0; i < config->num_streams; i++) {
@@ -3213,7 +3212,24 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
            dst.usage = mapToConsumerUsage(src->usage);
            dst.dataSpace = mapToHidlDataspace(src->data_space);
            dst.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);

            activeStreams.insert(streamId);
            // Create Buffer ID map if necessary
            if (mBufferIdMaps.count(streamId) == 0) {
                mBufferIdMaps.emplace(streamId, BufferIdMap{});
            }
        }
        // remove BufferIdMap for deleted streams
        for(auto it = mBufferIdMaps.begin(); it != mBufferIdMaps.end();) {
            int streamId = it->first;
            bool active = activeStreams.count(streamId) > 0;
            if (!active) {
                it = mBufferIdMaps.erase(it);
            } else {
                ++it;
            }
        }

        requestedConfiguration.operationMode = mapToStreamConfigurationMode(
                (camera3_stream_configuration_mode_t) config->operation_mode);

@@ -3310,8 +3326,13 @@ status_t Camera3Device::HalInterface::processCaptureRequest(
            std::lock_guard<std::mutex> lock(mInflightLock);
            if (request->input_buffer != nullptr) {
                int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
                buffer_handle_t buf = *(request->input_buffer->buffer);
                auto pair = getBufferId(buf, streamId);
                bool isNewBuffer = pair.first;
                uint64_t bufferId = pair.second;
                captureRequest.inputBuffer.streamId = streamId;
                captureRequest.inputBuffer.buffer = *(request->input_buffer->buffer);
                captureRequest.inputBuffer.bufferId = bufferId;
                captureRequest.inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
                captureRequest.inputBuffer.status = BufferStatus::OK;
                native_handle_t *acquireFence = nullptr;
                if (request->input_buffer->acquire_fence != -1) {
@@ -3323,7 +3344,11 @@ status_t Camera3Device::HalInterface::processCaptureRequest(
                captureRequest.inputBuffer.releaseFence = nullptr;

                pushInflightBufferLocked(captureRequest.frameNumber, streamId,
                        request->input_buffer->buffer);
                        request->input_buffer->buffer,
                        request->input_buffer->acquire_fence);
            } else {
                captureRequest.inputBuffer.streamId = -1;
                captureRequest.inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
            }

            captureRequest.outputBuffers.resize(request->num_output_buffers);
@@ -3331,8 +3356,12 @@ status_t Camera3Device::HalInterface::processCaptureRequest(
                const camera3_stream_buffer_t *src = request->output_buffers + i;
                StreamBuffer &dst = captureRequest.outputBuffers[i];
                int32_t streamId = Camera3Stream::cast(src->stream)->getId();
                buffer_handle_t buf = *(src->buffer);
                auto pair = getBufferId(buf, streamId);
                bool isNewBuffer = pair.first;
                dst.streamId = streamId;
                dst.buffer = *(src->buffer);
                dst.bufferId = pair.second;
                dst.buffer = isNewBuffer ? buf : nullptr;
                dst.status = BufferStatus::OK;
                native_handle_t *acquireFence = nullptr;
                if (src->acquire_fence != -1) {
@@ -3344,7 +3373,7 @@ status_t Camera3Device::HalInterface::processCaptureRequest(
                dst.releaseFence = nullptr;

                pushInflightBufferLocked(captureRequest.frameNumber, streamId,
                        src->buffer);
                        src->buffer, src->acquire_fence);
            }
        }
        common::V1_0::Status status = mHidlSession->processCaptureRequest(captureRequest);
@@ -3397,24 +3426,45 @@ status_t Camera3Device::HalInterface::close() {
}

status_t Camera3Device::HalInterface::pushInflightBufferLocked(
        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer) {
        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer, int acquireFence) {
    uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
    mInflightBufferMap[key] = buffer;
    auto pair = std::make_pair(buffer, acquireFence);
    mInflightBufferMap[key] = pair;
    return OK;
}

status_t Camera3Device::HalInterface::popInflightBuffer(
        int32_t frameNumber, int32_t streamId, /*out*/ buffer_handle_t **buffer) {
        int32_t frameNumber, int32_t streamId,
        /*out*/ buffer_handle_t **buffer) {
    std::lock_guard<std::mutex> lock(mInflightLock);

    uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
    auto it = mInflightBufferMap.find(key);
    if (it == mInflightBufferMap.end()) return NAME_NOT_FOUND;
    *buffer = it->second;
    auto pair = it->second;
    *buffer = pair.first;
    int acquireFence = pair.second;
    if (acquireFence > 0) {
        ::close(acquireFence);
    }
    mInflightBufferMap.erase(it);
    return OK;
}

std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
        const buffer_handle_t& buf, int streamId) {
    std::lock_guard<std::mutex> lock(mBufferIdMapLock);

    BufferIdMap& bIdMap = mBufferIdMaps.at(streamId);
    auto it = bIdMap.find(buf);
    if (it == bIdMap.end()) {
        bIdMap[buf] = mNextBufferId++;
        return std::make_pair(true, mNextBufferId - 1);
    } else {
        return std::make_pair(false, it->second);
    }
}

/**
 * RequestThread inner class methods
 */
+50 −2
Original line number Diff line number Diff line
@@ -262,9 +262,57 @@ class Camera3Device :
        std::mutex mInflightLock;

        status_t pushInflightBufferLocked(int32_t frameNumber, int32_t streamId,
                buffer_handle_t *buffer);
                buffer_handle_t *buffer, int acquireFence);
        // Cache of buffer handles keyed off (frameNumber << 32 | streamId)
        std::unordered_map<uint64_t, buffer_handle_t*> mInflightBufferMap;
        // value is a pair of (buffer_handle_t*, acquire_fence FD)
        std::unordered_map<uint64_t, std::pair<buffer_handle_t*, int>> mInflightBufferMap;

        struct BufferHasher {
            size_t operator()(const buffer_handle_t& buf) const {
                if (buf == nullptr)
                    return 0;

                size_t result = 1;
                result = 31 * result + buf->numFds;
                result = 31 * result + buf->numInts;
                int length = buf->numFds + buf->numInts;
                for (int i = 0; i < length; i++) {
                    result = 31 * result + buf->data[i];
                }
                return result;
            }
        };

        struct BufferComparator {
            bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
                if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) {
                    int length = buf1->numFds + buf1->numInts;
                    for (int i = 0; i < length; i++) {
                        if (buf1->data[i] != buf2->data[i]) {
                            return false;
                        }
                    }
                    return true;
                }
                return false;
            }
        };

        std::mutex mBufferIdMapLock; // protecting mBufferIdMaps and mNextBufferId
        typedef std::unordered_map<const buffer_handle_t, uint64_t,
                BufferHasher, BufferComparator> BufferIdMap;
        // stream ID -> per stream buffer ID map
        std::unordered_map<int, BufferIdMap> mBufferIdMaps;
        uint64_t mNextBufferId = 1; // 0 means no buffer
        static const uint64_t BUFFER_ID_NO_BUFFER = 0;

        // method to extract buffer's unique ID
        // TODO: we should switch to use gralloc mapper's getBackingStore API
        //       once we ran in binderized gralloc mode, but before that is ready,
        //       we need to rely on the conventional buffer queue behavior where
        //       buffer_handle_t's FD won't change.
        // return pair of (newlySeenBuffer?, bufferId)
        std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
    };

    std::unique_ptr<HalInterface> mInterface;