cameraserver: Implement HIDL ICameraDeviceUser and ICameraDeviceCallbacks.
Bug: 110364143
Test: (build) mm -j64
Change-Id: I2164b9ffacb3c00404a5a6506a4b6631663ee4c7
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
new file mode 100644
index 0000000..d22ba5a
--- /dev/null
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -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