cameraserver: Implement HIDL ICameraDeviceUser and ICameraDeviceCallbacks.

Bug: 110364143

Test: (build) mm -j64

Change-Id: I2164b9ffacb3c00404a5a6506a4b6631663ee4c7
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
gugelfrei
Jayant Chowdhary 6 years ago
parent 94f79a96b6
commit 0c94727f29

@ -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",

@ -0,0 +1,205 @@
/*
* 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

@ -0,0 +1,132 @@
/*
* 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

@ -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

@ -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

@ -0,0 +1,263 @@
/*
* 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 <android/hardware/camera/device/3.2/types.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <hidl/AidlCameraDeviceCallbacks.h>
#include <hidl/Convert.h>
#include <hidl/HidlCameraDeviceUser.h>
#include <android/hardware/camera/device/3.2/types.h>
namespace android {
namespace frameworks {
namespace cameraservice {
namespace device {
namespace V2_0 {
namespace implementation {
using hardware::cameraservice::utils::conversion::convertToHidl;
using hardware::cameraservice::utils::conversion::convertFromHidl;
using hardware::cameraservice::utils::conversion::B2HStatus;
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
using hardware::hidl_vec;
using hardware::Return;
using hardware::Void;
using HSubmitInfo = device::V2_0::SubmitInfo;
using hardware::camera2::params::OutputConfiguration;
static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
Return<void> HidlCameraDeviceUser::disconnect() {
mDeviceRemote->disconnect();
return Void();
}
HidlCameraDeviceUser::HidlCameraDeviceUser(
const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
: mDeviceRemote(deviceRemote) {
mInitSuccess = initDevice();
}
bool HidlCameraDeviceUser::initDevice() {
// TODO: Get request and result metadata queue size from a system property.
int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
mCaptureRequestMetadataQueue =
std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
false /* non blocking */);
if (!mCaptureRequestMetadataQueue->isValid()) {
ALOGE("%s: invalid request fmq", __FUNCTION__);
return false;
}
int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
mCaptureResultMetadataQueue =
std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
false /* non blocking */);
if (!mCaptureResultMetadataQueue->isValid()) {
ALOGE("%s: invalid result fmq", __FUNCTION__);
return false;
}
return true;
}
Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
getCaptureRequestMetadataQueue_cb _hidl_cb) {
if (mInitSuccess) {
_hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
}
return Void();
}
Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
getCaptureResultMetadataQueue_cb _hidl_cb) {
if (mInitSuccess) {
_hidl_cb(*mCaptureResultMetadataQueue->getDesc());
}
return Void();
}
/**
* To be used only by submitRequestList implementation, since it requires
* clients to call this method serially, incase fmq is used to send metadata.
*/
bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
bool converted = false;
for (auto &e : hPhysicalCameraSettings) {
physicalCameraSettings->emplace_back();
CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
physicalCameraSettings->back();
physicalCameraSetting.id = e.id.c_str();
// Read the settings either from the fmq or straightaway from the
// request. We don't need any synchronization, since submitRequestList
// is guaranteed to be called serially by the client if it decides to
// use fmq.
if (e.settings.getDiscriminator() ==
FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
/**
* Get settings from the fmq.
*/
HCameraMetadata settingsFmq;
settingsFmq.resize(e.settings.fmqMetadataSize());
bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
e.settings.fmqMetadataSize());
if (!read) {
ALOGE("%s capture request settings could't be read from fmq size",
__FUNCTION__);
converted = false;
} else {
converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
}
} else {
/**
* The settings metadata is contained in request settings field.
*/
converted =
convertFromHidl(e.settings.metadata(),
&physicalCameraSetting.settings);
}
if (!converted) {
ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
return false;
}
}
return true;
}
bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
CaptureRequest *request) {
// No reprocessing support.
request->mIsReprocess = false;
for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
request->mStreamIdxList.push_back(streamAndWindowId.streamId);
request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
}
return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
&(request->mPhysicalCameraSettings));
}
Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
bool streaming,
submitRequestList_cb _hidl_cb) {
hardware::camera2::utils::SubmitInfo submitInfo;
HSubmitInfo hSubmitInfo;
/**
* Create AIDL CaptureRequest from requestList and graphicBufferProducers.
*/
std::vector<hardware::camera2::CaptureRequest> requests;
for (auto &hRequest : hRequestList) {
requests.emplace_back();
auto &request = requests.back();
if (!convertRequestFromHidl(hRequest, &request)) {
_hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
return Void();
}
}
mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
mRequestId = submitInfo.mRequestId;
convertToHidl(submitInfo, &hSubmitInfo);
_hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
return Void();
}
Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
int64_t lastFrameNumber = 0;
binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
_hidl_cb(B2HStatus(ret), lastFrameNumber);
return Void();
}
Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
binder::Status ret = mDeviceRemote->beginConfigure();
return B2HStatus(ret);
}
Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
const hidl_vec<uint8_t>& sessionParams) {
android::CameraMetadata cameraMetadata;
if (!convertFromHidl(sessionParams, &cameraMetadata)) {
return HStatus::ILLEGAL_ARGUMENT;
}
binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
cameraMetadata);
return B2HStatus(ret);
}
Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
binder::Status ret = mDeviceRemote->deleteStream(streamId);
return B2HStatus(ret);
}
Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
createStream_cb hidl_cb_) {
OutputConfiguration outputConfiguration =
convertFromHidl(hOutputConfiguration);
int32_t newStreamId = 0;
binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
HStatus status = B2HStatus(ret);
hidl_cb_(status, newStreamId);
return Void();
}
Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
createDefaultRequest_cb _hidl_cb) {
android::CameraMetadata cameraMetadata;
binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
&cameraMetadata);
HStatus hStatus = B2HStatus(ret);
HCameraMetadata hidlMetadata;
const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
convertToHidl(rawMetadata, &hidlMetadata);
_hidl_cb(hStatus, hidlMetadata);
cameraMetadata.unlock(rawMetadata);
return Void();
}
Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
binder::Status ret = mDeviceRemote->waitUntilIdle();
return B2HStatus(ret);
}
Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
int64_t lastFrameNumber = 0;
binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
_hidl_cb(B2HStatus(ret),lastFrameNumber);
return Void();
}
Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
int32_t streamId,
const HOutputConfiguration& hOutputConfiguration) {
OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
return B2HStatus(ret);
}
} // implementation
} // V2_0
} // device
} // cameraservice
} // frameworks
} // android

@ -0,0 +1,128 @@
/*
* 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_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
#define ANDROID_FRAMEWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
#include <mutex>
#include <memory>
#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/ICameraDeviceUser.h>
#include <android/frameworks/cameraservice/device/2.0/types.h>
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <CameraService.h>
namespace android {
namespace frameworks {
namespace cameraservice {
namespace device {
namespace V2_0 {
namespace implementation {
using frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
using hardware::camera2::CaptureRequest;
using hardware::hidl_vec;
using hardware::kSynchronizedReadWrite;
using hardware::MessageQueue;
using hardware::MQDescriptorSync;
using hardware::Return;
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using CaptureRequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
using HCameraDeviceUser = device::V2_0::ICameraDeviceUser;
using HCameraMetadata = cameraservice::service::V2_0::CameraMetadata;
using HCaptureRequest = device::V2_0::CaptureRequest;
using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
using HStatus = frameworks::cameraservice::common::V2_0::Status;
static constexpr int32_t REQUEST_ID_NONE = -1;
struct HidlCameraDeviceUser final : public HCameraDeviceUser {
HidlCameraDeviceUser(const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote);
~HidlCameraDeviceUser() { }
virtual Return<void> disconnect() override;
virtual Return<void> getCaptureRequestMetadataQueue(
getCaptureRequestMetadataQueue_cb _hidl_cb) override;
virtual Return<void> getCaptureResultMetadataQueue(
getCaptureResultMetadataQueue_cb _hidl_cb) override;
virtual Return<void> submitRequestList(const hidl_vec<HCaptureRequest>& requestList,
bool streaming, submitRequestList_cb _hidl_cb) override;
virtual Return<void> cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) override;
virtual Return<HStatus> beginConfigure() override;
virtual Return<HStatus> endConfigure(StreamConfigurationMode operatingMode,
const hidl_vec<uint8_t>& sessionParams);
virtual Return<HStatus> deleteStream(int32_t streamId) override;
virtual Return<void> createStream(const HOutputConfiguration& outputConfiguration,
createStream_cb _hidl_cb) override;
Return<void> createDefaultRequest(TemplateId templateId,
createDefaultRequest_cb _hidl_cb) override;
virtual Return<HStatus> waitUntilIdle() override;
virtual Return<void> flush(flush_cb _hidl_cb) override;
virtual Return<HStatus> updateOutputConfiguration(
int32_t streamId, const HOutputConfiguration& outputConfiguration) override;
bool initStatus() { return mInitSuccess; }
std::shared_ptr<CaptureResultMetadataQueue> getCaptureResultMetadataQueue() {
return mCaptureResultMetadataQueue;
}
private:
bool initDevice();
bool convertRequestFromHidl(const HCaptureRequest &hRequest, CaptureRequest *request);
bool copyPhysicalCameraSettings(
const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings);
const sp<hardware::camera2::ICameraDeviceUser> mDeviceRemote;
std::unique_ptr<CaptureRequestMetadataQueue> mCaptureRequestMetadataQueue = nullptr;
std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
bool mInitSuccess = false;
int32_t mRequestId = REQUEST_ID_NONE;
};
} // implementation
} // V2_0
} // device
} // cameraservice
} // frameworks
} // android
#endif // ANDROID_FRAMEOWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H

@ -17,6 +17,9 @@
#include <hidl/Convert.h>
#include <hidl/HidlCameraService.h>
#include <hidl/HidlCameraDeviceUser.h>
#include <hidl/AidlCameraDeviceCallbacks.h>
#include <hidl/AidlCameraServiceListener.h>
#include <hidl/HidlTransportSupport.h>
@ -34,6 +37,8 @@ using hardware::cameraservice::utils::conversion::convertToHidl;
using hardware::cameraservice::utils::conversion::B2HStatus;
using hardware::Void;
using device::V2_0::implementation::H2BCameraDeviceCallbacks;
using device::V2_0::implementation::HidlCameraDeviceUser;
using service::V2_0::implementation::H2BCameraServiceListener;
using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
@ -79,11 +84,43 @@ HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
const hidl_string& cameraId,
connectDevice_cb _hidl_cb) {
// To silence Wunused-parameter.
(void)hCallback;
(void)cameraId;
(void)_hidl_cb;
// Here, we first get ICameraDeviceUser from mAidlICameraService, then save
// that interface in the newly created HidlCameraDeviceUser impl class.
if (mAidlICameraService == nullptr) {
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
return Void();
}
sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
// Create a hardware::camera2::ICameraDeviceCallback object which internally
// calls callback functions passed through hCallback.
sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
if (!hybridCallbacks->initializeLooper()) {
ALOGE("Unable to handle callbacks on device, cannot connect");
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
return Void();
}
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
binder::Status serviceRet = mAidlICameraService->connectDevice(
callbacks, String16(cameraId.c_str()), String16(""),
hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
status = B2HStatus(serviceRet);
_hidl_cb(status, nullptr);
return Void();
}
// Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
// and return that back. All calls on that interface will be forwarded to
// the AIDL interface.
sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
if (!hDeviceRemote->initStatus()) {
ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
return Void();
}
hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
_hidl_cb(status, hDeviceRemote);
return Void();
}

Loading…
Cancel
Save