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

Commit 0c94727f authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

cameraserver: Implement HIDL ICameraDeviceUser and ICameraDeviceCallbacks.



Bug: 110364143

Test: (build) mm -j64

Change-Id: I2164b9ffacb3c00404a5a6506a4b6631663ee4c7
Signed-off-by: default avatarJayant Chowdhary <jchowdhary@google.com>
parent 94f79a96
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -53,9 +53,11 @@ cc_library_shared {
        "device3/DistortionMapper.cpp",
        "gui/RingBufferConsumer.cpp",
        "utils/CameraThreadState.cpp",
        "hidl/AidlCameraDeviceCallbacks.cpp",
        "hidl/AidlCameraServiceListener.cpp",
        "hidl/HidlCameraService.cpp",
        "hidl/Convert.cpp",
        "hidl/HidlCameraDeviceUser.cpp",
        "hidl/HidlCameraService.cpp",
        "utils/CameraTraces.cpp",
        "utils/AutoConditionLock.cpp",
        "utils/TagMonitor.cpp",
@@ -82,6 +84,7 @@ cc_library_shared {
        "libhidltransport",
        "libjpeg",
        "libmemunreachable",
        "libstagefright_foundation",
        "android.frameworks.cameraservice.common@2.0",
        "android.frameworks.cameraservice.service@2.0",
        "android.frameworks.cameraservice.device@2.0",
+205 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */
#include <hardware/camera.h>

#include <hidl/AidlCameraDeviceCallbacks.h>
#include <hidl/Convert.h>

namespace android {
namespace frameworks {
namespace cameraservice {
namespace device {
namespace V2_0 {
namespace implementation {

using hardware::hidl_vec;
using HCaptureResultExtras = android::frameworks::cameraservice::device::V2_0::CaptureResultExtras;
using HPhysicalCaptureResultInfo = android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
using HCameraMetadata = android::frameworks::cameraservice::device::V2_0::CameraMetadata;

const char *H2BCameraDeviceCallbacks::kResultKey = "CaptureResult";

H2BCameraDeviceCallbacks::H2BCameraDeviceCallbacks(const sp<HalInterface>& base) : CBase(base) { }

bool H2BCameraDeviceCallbacks::initializeLooper() {
    mCbLooper = new ALooper;
    mCbLooper->setName("cs-looper");
    status_t err = mCbLooper->start(/*runOnCallingThread*/ false, /*canCallJava*/ false,
                                    PRIORITY_DEFAULT);
    if (err !=OK) {
        ALOGE("Unable to start camera device callback looper");
        return false;
    }
    mHandler = new CallbackHandler(this);
    mCbLooper->registerHandler(mHandler);
    return true;
}

H2BCameraDeviceCallbacks::~H2BCameraDeviceCallbacks() {
    if (mCbLooper != nullptr) {
        if (mHandler != nullptr) {
            mCbLooper->unregisterHandler(mHandler->id());
        }
        mCbLooper->stop();
    }
    mCbLooper.clear();
    mHandler.clear();
}

binder::Status H2BCameraDeviceCallbacks::onDeviceError(
    int32_t errorCode, const CaptureResultExtras& resultExtras) {
    using hardware::cameraservice::utils::conversion::convertToHidl;
    HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
    auto ret = mBase->onDeviceError(convertToHidl(errorCode), hCaptureResultExtras);
    if (!ret.isOk()) {
        ALOGE("%s OnDeviceError callback failed due to %s",__FUNCTION__,
              ret.description().c_str());
    }
    return binder::Status::ok();
}

binder::Status H2BCameraDeviceCallbacks::onDeviceIdle() {
    auto ret = mBase->onDeviceIdle();
    if (!ret.isOk()) {
          ALOGE("%s OnDeviceIdle callback failed due to %s",__FUNCTION__,
                ret.description().c_str());
    }
    return binder::Status::ok();
}

binder::Status H2BCameraDeviceCallbacks::onCaptureStarted(
    const CaptureResultExtras& resultExtras, int64_t timestamp) {
    using hardware::cameraservice::utils::conversion::convertToHidl;
    HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
    auto ret = mBase->onCaptureStarted(hCaptureResultExtras, timestamp);
    if (!ret.isOk()) {
        ALOGE("%s OnCaptureCallback failed due to %s",__FUNCTION__,
              ret.description().c_str());
    }
    return binder::Status::ok();
}

void H2BCameraDeviceCallbacks::convertResultMetadataToHidl(const camera_metadata_t *rawMetadata,
                                                           FmqSizeOrMetadata *hResultMetadata) {
    // First try writing to fmq.
    size_t metadata_size = get_camera_metadata_size(rawMetadata);
    if ((metadata_size > 0) &&
        (mCaptureResultMetadataQueue->availableToWrite() > 0)) {
        if (mCaptureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
            hResultMetadata->fmqMetadataSize(metadata_size);
        } else {
            ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
            HCameraMetadata metadata;
            hardware::cameraservice::utils::conversion::convertToHidl(rawMetadata, &metadata);
            hResultMetadata->metadata(std::move(metadata));
        }
    }
}

void H2BCameraDeviceCallbacks::CallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
    sp<RefBase> obj = nullptr;
    sp<ResultWrapper> resultWrapper = nullptr;
    bool found = false;
    switch (msg->what()) {
        case kWhatResultReceived:
            found = msg->findObject(kResultKey, &obj);
            if (!found || obj == nullptr) {
                ALOGE("Cannot find result object in callback message");
                return;
            }
            resultWrapper = static_cast<ResultWrapper *>(obj.get());
            processResultMessage(resultWrapper);
            break;
        default:
            ALOGE("Unknown callback sent");
            break;
    }
    return;
}

void H2BCameraDeviceCallbacks::CallbackHandler::processResultMessage(
    sp<ResultWrapper> &resultWrapper) {
    sp<H2BCameraDeviceCallbacks> converter = mConverter.promote();
    if (converter == nullptr) {
        ALOGE("Callback wrapper has died, result callback cannot be made");
        return;
    }
    CameraMetadataNative &result = resultWrapper->mResult;
    auto resultExtras = resultWrapper->mResultExtras;
    auto &physicalCaptureResultInfos = resultWrapper->mPhysicalCaptureResultInfos;
    HCaptureResultExtras hResultExtras =
            hardware::cameraservice::utils::conversion::convertToHidl(resultExtras);
    hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos =
            hardware::cameraservice::utils::conversion::convertToHidl(
                    physicalCaptureResultInfos, converter->mCaptureResultMetadataQueue);

    // Convert Metadata into HCameraMetadata;
    FmqSizeOrMetadata hResult;
    const camera_metadata_t *rawMetadata = result.getAndLock();
    converter->convertResultMetadataToHidl(rawMetadata, &hResult);
    result.unlock(rawMetadata);
    auto ret = converter->mBase->onResultReceived(hResult, hResultExtras,
                                                  hPhysicalCaptureResultInfos);
    if (!ret.isOk()) {
          ALOGE("%s OnResultReceived callback failed due to %s",__FUNCTION__,
                ret.description().c_str());
    }
}

binder::Status H2BCameraDeviceCallbacks::onResultReceived(
    const CameraMetadataNative& result,
    const CaptureResultExtras& resultExtras,
    const ::std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) {
    // Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on
    // sp<RefBase>-able structure and post it.
    sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result),
                                                        resultExtras, physicalCaptureResultInfos);
    sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler);
    msg->setObject(kResultKey, resultWrapper);
    msg->post();
    return binder::Status::ok();
}

binder::Status H2BCameraDeviceCallbacks::onPrepared(int32_t streamId) {
    // not implemented
    // To silence Wunused-parameter.
    (void) streamId;
    return binder::Status::ok();
}

binder::Status H2BCameraDeviceCallbacks::onRepeatingRequestError(
    int64_t lastFrameNumber,
    int32_t repeatingRequestId) {
    auto ret =
        mBase->onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
    if (!ret.isOk()) {
        ALOGE("%s OnRepeatingRequestEror callback failed due to %s",__FUNCTION__,
              ret.description().c_str());
    }
    return binder::Status::ok();
}

binder::Status H2BCameraDeviceCallbacks::onRequestQueueEmpty() {
    // not implemented
    return binder::Status::ok();
}

} // implementation
} // V2_0
} // device
} // cameraservice
} // frameworks
} // android
+132 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */

#ifndef ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
#define ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H

#include <mutex>
#include <thread>

#include <android/frameworks/cameraservice/common/2.0/types.h>
#include <android/frameworks/cameraservice/service/2.0/types.h>
#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceCallback.h>
#include <android/frameworks/cameraservice/device/2.0/types.h>
#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/AMessage.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <CameraService.h>
#include <hidl/CameraHybridInterface.h>

namespace android {
namespace frameworks {
namespace cameraservice {
namespace device {
namespace V2_0 {
namespace implementation {

using camerahybrid::H2BConverter;
using HCameraDeviceCallback = cameraservice::device::V2_0::ICameraDeviceCallback;
using HPhysicalCaptureResultInfo = cameraservice::device::V2_0::PhysicalCaptureResultInfo;
using android::frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;

using hardware::camera2::BnCameraDeviceCallbacks;
using hardware::camera2::ICameraDeviceCallbacks;
using hardware::camera2::impl::CaptureResultExtras;
using hardware::camera2::impl::CameraMetadataNative;
using hardware::camera2::impl::PhysicalCaptureResultInfo;
using hardware::kSynchronizedReadWrite;
using hardware::MessageQueue;
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;

struct H2BCameraDeviceCallbacks :
    public H2BConverter<HCameraDeviceCallback, ICameraDeviceCallbacks, BnCameraDeviceCallbacks> {
    H2BCameraDeviceCallbacks(const sp<HalInterface>& base);

    ~H2BCameraDeviceCallbacks();

    bool initializeLooper();

    virtual binder::Status onDeviceError(int32_t errorCode,
                                         const CaptureResultExtras& resultExtras) override;

    virtual binder::Status onDeviceIdle() override;

    virtual binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
                                            int64_t timestamp) override;

    virtual binder::Status onResultReceived(
        const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
        const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;

    virtual binder::Status onPrepared(int32_t streamId) override;

    virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
                                                   int32_t repeatingRequestId) override;

    virtual binder::Status onRequestQueueEmpty() override;

    void setCaptureResultMetadataQueue(std::shared_ptr<CaptureResultMetadataQueue> metadataQueue) {
        mCaptureResultMetadataQueue = metadataQueue;
    }

 private:
    // Wrapper struct so that parameters to onResultReceived callback may be
    // sent through an AMessage.
    struct ResultWrapper : public RefBase {
        CameraMetadataNative mResult;
        CaptureResultExtras mResultExtras;
        std::vector<PhysicalCaptureResultInfo> mPhysicalCaptureResultInfos;
        ResultWrapper(CameraMetadataNative &result,
                      const CaptureResultExtras resultExtras,
                      const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos) :
      // TODO: make this std::movable
      mResult(result), mResultExtras(resultExtras), mPhysicalCaptureResultInfos(physicalCaptureResultInfos) { }
    };

    struct CallbackHandler : public AHandler {
        public:
            void onMessageReceived(const sp<AMessage> &msg) override;
            CallbackHandler(H2BCameraDeviceCallbacks *converter) : mConverter(converter) { }
        private:
            void processResultMessage(sp<ResultWrapper> &resultWrapper);
            wp<H2BCameraDeviceCallbacks> mConverter = nullptr;
            Mutex mMetadataQueueLock;
    };

    void convertResultMetadataToHidl(const camera_metadata *rawMetadata,
                                     FmqSizeOrMetadata *resultMetadata);
    enum {
        kWhatResultReceived,
    };

    static const char *kResultKey;

    std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
    sp<CallbackHandler> mHandler = nullptr;
    sp<ALooper> mCbLooper = nullptr;
};

} // implementation
} // V2_0
} // device
} // cameraservice
} // frameworks
} // android
#endif // ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
+37 −0
Original line number Diff line number Diff line
@@ -220,6 +220,43 @@ HStatus B2HStatus(const binder::Status &bStatus) {
  return status;
}

HPhysicalCaptureResultInfo convertToHidl(
    const PhysicalCaptureResultInfo &physicalCaptureResultInfo,
    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
    HPhysicalCaptureResultInfo hPhysicalCaptureResultInfo;
    hPhysicalCaptureResultInfo.physicalCameraId =
        String8(physicalCaptureResultInfo.mPhysicalCameraId).string();
    const camera_metadata_t *rawMetadata =
        physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
    // Try using fmq at first.
    size_t metadata_size = get_camera_metadata_size(rawMetadata);
    if ((metadata_size > 0) && (captureResultMetadataQueue->availableToWrite() > 0)) {
        if (captureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
            hPhysicalCaptureResultInfo.physicalCameraMetadata.fmqMetadataSize(metadata_size);
        } else {
            ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
            HCameraMetadata metadata;
            convertToHidl(rawMetadata, &metadata);
            hPhysicalCaptureResultInfo.physicalCameraMetadata.metadata(std::move(metadata));
        }
    }
    physicalCaptureResultInfo.mPhysicalCameraMetadata.unlock(rawMetadata);
    return hPhysicalCaptureResultInfo;
}

hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
    const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
    hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos;
    hPhysicalCaptureResultInfos.resize(physicalCaptureResultInfos.size());
    size_t i = 0;
    for (auto &physicalCaptureResultInfo : physicalCaptureResultInfos) {
        hPhysicalCaptureResultInfos[i++] = convertToHidl(physicalCaptureResultInfo,
                                                         captureResultMetadataQueue);
    }
    return hPhysicalCaptureResultInfos;
}

} //conversion
} // utils
} //cameraservice
+7 −0
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@
#include <android/hardware/camera2/ICameraDeviceUser.h>
#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
#include <android/hardware/ICameraService.h>
#include <fmq/MessageQueue.h>
#include <hardware/camera.h>
#include <hidl/MQDescriptor.h>

namespace android {
namespace hardware {
@@ -39,6 +41,7 @@ namespace conversion {
using hardware::camera2::impl::CaptureResultExtras;
using hardware::camera2::impl::PhysicalCaptureResultInfo;

using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
@@ -79,6 +82,10 @@ HErrorCode convertToHidl(int32_t errorCode);

HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras);

hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
    const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
    std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue);

HStatus B2HStatus(const binder::Status &bStatus);

} // conversion
Loading