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

Commit c9e4122f authored by Changyeon Jo's avatar Changyeon Jo
Browse files

Implement incomplete or missing IEvsCamera methods

This CL completes IEvsCamera interface implementation by adding
following methods to a default AIDL EVS HAL implementation.
- IEvsCamera::importExternalBuffers()
- IEvsCamera::getIntParameterRange()
- IEvsCamera::setIntParameter()
- IEvsCamera::getIntParameter()

Fix: 275101894
Test: 1. Launch CVD in accelerated graphics mode (gfxstream).
      2. atest VtsHalEvsTargetTest --iteration 3
Change-Id: I70ed2a97f49d27146ce00cdaab9ca3f41a59fc98
parent 452fefe4
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -146,7 +146,21 @@ class EvsMockCamera : public evs::BnEvsCamera {

    // For the extended info
    std::unordered_map<uint32_t, std::vector<uint8_t>> mExtInfo;
    std::unordered_map<CameraParam, int32_t> mParams;

    // For the camera parameters.
    struct CameraParameterDesc {
        CameraParameterDesc(int min = 0, int max = 0, int step = 0, int value = 0) {
            this->range.min = min;
            this->range.max = max;
            this->range.step = step;
            this->value = value;
        }

        ParameterRange range;
        int32_t value;
    };
    std::unordered_map<CameraParam, std::shared_ptr<CameraParameterDesc>> mParams;
    void initializeParameters();
};

}  // namespace aidl::android::hardware::automotive::evs::implementation
+108 −15
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ EvsMockCamera::EvsMockCamera([[maybe_unused]] Sigil sigil, const char* id,
        const size_t len = get_camera_metadata_size(camInfo->characteristics);
        mDescription.metadata.insert(mDescription.metadata.end(), ptr, ptr + len);
    }

    // Initialize parameters.
    initializeParameters();
}

EvsMockCamera::~EvsMockCamera() {
@@ -75,6 +78,18 @@ EvsMockCamera::~EvsMockCamera() {
    shutdown();
}

void EvsMockCamera::initializeParameters() {
    mParams.emplace(
            CameraParam::BRIGHTNESS,
            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
    mParams.emplace(
            CameraParam::CONTRAST,
            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
    mParams.emplace(
            CameraParam::SHARPNESS,
            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
}

// This gets called if another caller "steals" ownership of the camera
void EvsMockCamera::shutdown() {
    LOG(DEBUG) << __FUNCTION__;
@@ -291,29 +306,107 @@ ScopedAStatus EvsMockCamera::getParameterList(std::vector<CameraParam>* _aidl_re
    return ScopedAStatus::ok();
}

ScopedAStatus EvsMockCamera::getIntParameterRange([[maybe_unused]] CameraParam id,
                                                  [[maybe_unused]] ParameterRange* _aidl_return) {
ScopedAStatus EvsMockCamera::getIntParameterRange(CameraParam id, ParameterRange* _aidl_return) {
    auto it = mParams.find(id);
    if (it == mParams.end()) {
        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
    }

ScopedAStatus EvsMockCamera::setIntParameter(
        [[maybe_unused]] CameraParam id, [[maybe_unused]] int32_t value,
        [[maybe_unused]] std::vector<int32_t>* effectiveValue) {
    return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
    _aidl_return->min = it->second->range.min;
    _aidl_return->max = it->second->range.max;
    _aidl_return->step = it->second->range.step;
    return ScopedAStatus::ok();
}

ScopedAStatus EvsMockCamera::getIntParameter([[maybe_unused]] CameraParam id,
                                             [[maybe_unused]] std::vector<int32_t>* value) {
ScopedAStatus EvsMockCamera::setIntParameter(CameraParam id, int32_t value,
                                             std::vector<int32_t>* effectiveValue) {
    auto it = mParams.find(id);
    if (it == mParams.end()) {
        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
    }

ScopedAStatus EvsMockCamera::importExternalBuffers(
        [[maybe_unused]] const std::vector<BufferDesc>& buffers,
        [[maybe_unused]] int32_t* _aidl_return) {
    LOG(DEBUG) << "This implementation does not support an external buffer import.";
    // Rounding down to the closest value.
    int32_t candidate = value / it->second->range.step * it->second->range.step;
    if (candidate < it->second->range.min || candidate > it->second->range.max) {
        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
    }

    it->second->value = candidate;
    effectiveValue->push_back(candidate);
    return ScopedAStatus::ok();
}

ScopedAStatus EvsMockCamera::getIntParameter(CameraParam id, std::vector<int32_t>* value) {
    auto it = mParams.find(id);
    if (it == mParams.end()) {
        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
    }

    value->push_back(it->second->value);
    return ScopedAStatus::ok();
}

ScopedAStatus EvsMockCamera::importExternalBuffers(const std::vector<BufferDesc>& buffers,
                                                   int32_t* _aidl_return) {
    size_t numBuffersToAdd = buffers.size();
    if (numBuffersToAdd < 1) {
        LOG(DEBUG) << "Ignoring a request to import external buffers with an empty list.";
        return ScopedAStatus::ok();
    }

    std::lock_guard lock(mAccessLock);
    if (numBuffersToAdd > (kMaxBuffersInFlight - mFramesAllowed)) {
        numBuffersToAdd -= (kMaxBuffersInFlight - mFramesAllowed);
        LOG(WARNING) << "Exceed the limit on the number of buffers. " << numBuffersToAdd
                     << " buffers will be imported only.";
    }

    ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
    const size_t before = mFramesAllowed;
    for (size_t i = 0; i < numBuffersToAdd; ++i) {
        auto& b = buffers[i];
        const AHardwareBuffer_Desc* pDesc =
                reinterpret_cast<const AHardwareBuffer_Desc*>(&b.buffer.description);

        buffer_handle_t handleToImport = ::android::dupFromAidl(b.buffer.handle);
        buffer_handle_t handleToStore = nullptr;
        if (handleToImport == nullptr) {
            LOG(WARNING) << "Failed to duplicate a memory handle. Ignoring a buffer " << b.bufferId;
            continue;
        }

        ::android::status_t result =
                mapper.importBuffer(handleToImport, pDesc->width, pDesc->height, pDesc->layers,
                                    pDesc->format, pDesc->usage, pDesc->stride, &handleToStore);
        if (result != ::android::NO_ERROR || handleToStore == nullptr) {
            LOG(WARNING) << "Failed to import a buffer " << b.bufferId;
            continue;
        }

        bool stored = false;
        for (auto&& rec : mBuffers) {
            if (rec.handle != nullptr) {
                continue;
            }

            // Use this existing entry.
            rec.handle = handleToStore;
            rec.inUse = false;
            stored = true;
            break;
        }

        if (!stored) {
            // Add a BufferRecord wrapping this handle to our set of available buffers.
            mBuffers.push_back(BufferRecord(handleToStore));
        }
        ++mFramesAllowed;
    }

    *_aidl_return = mFramesAllowed - before;
    return ScopedAStatus::ok();
}

bool EvsMockCamera::setAvailableFrames_Locked(unsigned bufferCount) {
    if (bufferCount < 1) {
        LOG(ERROR) << "Ignoring request to set buffer count to zero";