Merge Android U (ab/10368041)
Bug: 291102124
Merged-In: Ied8e295ae059db07463ba06d3e6d747659b2757f
Change-Id: Ib79234b765308e957b682871b2178b66769f5660
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
new file mode 100644
index 0000000..e648a36
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "AidlCameraDeviceCallbacks"
+
+#include <aidl/AidlCameraDeviceCallbacks.h>
+#include <aidl/AidlUtils.h>
+#include <aidl/android/frameworks/cameraservice/common/Status.h>
+#include <hidl/Utils.h>
+#include <utility>
+
+namespace android::frameworks::cameraservice::device::implementation {
+
+// VNDK classes
+using SCameraMetadata = ::aidl::android::frameworks::cameraservice::device::CameraMetadata;
+using SCaptureResultExtras =
+ ::aidl::android::frameworks::cameraservice::device::CaptureResultExtras;
+using SPhysicalCaptureResultInfo =
+ ::aidl::android::frameworks::cameraservice::device::PhysicalCaptureResultInfo;
+using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
+// NDK classes
+using UCaptureResultExtras = ::android::hardware::camera2::impl::CaptureResultExtras;
+using UPhysicalCaptureResultInfo = ::android::hardware::camera2::impl::PhysicalCaptureResultInfo;
+
+using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
+
+const char *AidlCameraDeviceCallbacks::kResultKey = "CaptureResult";
+
+
+bool AidlCameraDeviceCallbacks::initializeLooper(int vndkVersion) {
+ 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, vndkVersion);
+ mCbLooper->registerHandler(mHandler);
+ return true;
+}
+
+AidlCameraDeviceCallbacks::AidlCameraDeviceCallbacks(
+ const std::shared_ptr<SICameraDeviceCallback>& base):
+ mBase(base), mDeathPipe(this, base->asBinder()) {}
+
+AidlCameraDeviceCallbacks::~AidlCameraDeviceCallbacks() {
+ if (mCbLooper != nullptr) {
+ if (mHandler != nullptr) {
+ mCbLooper->unregisterHandler(mHandler->id());
+ }
+ mCbLooper->stop();
+ }
+ mCbLooper.clear();
+ mHandler.clear();
+}
+
+binder::Status AidlCameraDeviceCallbacks::onDeviceError(
+ int32_t errorCode, const CaptureResultExtras& resultExtras) {
+ using hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+ SCaptureResultExtras cre = convertToAidl(resultExtras);
+ auto ret = mBase->onDeviceError(convertToAidl(errorCode), cre);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onDeviceError")
+ return binder::Status::ok();
+}
+
+binder::Status AidlCameraDeviceCallbacks::onDeviceIdle() {
+ auto ret = mBase->onDeviceIdle();
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onDeviceIdle")
+ return binder::Status::ok();
+}
+
+binder::Status AidlCameraDeviceCallbacks::onCaptureStarted(
+ const CaptureResultExtras& resultExtras, int64_t timestamp) {
+ using hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+ SCaptureResultExtras hCaptureResultExtras = convertToAidl(resultExtras);
+ auto ret = mBase->onCaptureStarted(hCaptureResultExtras, timestamp);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onCaptureStarted")
+ return binder::Status::ok();
+}
+
+void AidlCameraDeviceCallbacks::convertResultMetadataToAidl(const camera_metadata_t* src,
+ SCaptureMetadataInfo* dst) {
+ // First try writing to fmq.
+ size_t metadata_size = get_camera_metadata_size(src);
+ if ((metadata_size > 0) &&
+ (mCaptureResultMetadataQueue->availableToWrite() > 0)) {
+ if (mCaptureResultMetadataQueue->write((int8_t *)src, metadata_size)) {
+ dst->set<SCaptureMetadataInfo::fmqMetadataSize>(metadata_size);
+ } else {
+ ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
+ SCameraMetadata metadata;
+ hardware::cameraservice::utils::conversion::aidl::cloneToAidl(src, &metadata);
+ dst->set<SCaptureMetadataInfo::metadata>(std::move(metadata));
+ }
+ }
+}
+
+void AidlCameraDeviceCallbacks::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;
+ }
+ }
+
+void AidlCameraDeviceCallbacks::CallbackHandler::processResultMessage(
+ sp<ResultWrapper> &resultWrapper) {
+ sp<AidlCameraDeviceCallbacks> 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;
+ SCaptureResultExtras convResultExtras =
+ hardware::cameraservice::utils::conversion::aidl::convertToAidl(resultExtras);
+
+ // Convert Metadata into HCameraMetadata;
+ SCaptureMetadataInfo captureMetadataInfo;
+ if (filterVndkKeys(mVndkVersion, result, /*isStatic*/false) != OK) {
+ ALOGE("%s: filtering vndk keys from result failed, not sending onResultReceived callback",
+ __FUNCTION__);
+ return;
+ }
+ const camera_metadata_t *rawMetadata = result.getAndLock();
+ converter->convertResultMetadataToAidl(rawMetadata, &captureMetadataInfo);
+ result.unlock(rawMetadata);
+
+ auto &physicalCaptureResultInfos = resultWrapper->mPhysicalCaptureResultInfos;
+ std::vector<SPhysicalCaptureResultInfo> stableCaptureResInfo =
+ convertToAidl(physicalCaptureResultInfos, converter->mCaptureResultMetadataQueue);
+ auto ret = converter->mBase->onResultReceived(captureMetadataInfo,
+ convResultExtras,
+ stableCaptureResInfo);
+
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "OnResultReceived")
+}
+
+binder::Status AidlCameraDeviceCallbacks::onResultReceived(
+ const CameraMetadataNative& result,
+ const UCaptureResultExtras& resultExtras,
+ const ::std::vector<UPhysicalCaptureResultInfo>& 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 AidlCameraDeviceCallbacks::onPrepared(int32_t streamId) {
+ auto ret = mBase->onPrepared(streamId);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onPrepared")
+ return binder::Status::ok();
+}
+
+binder::Status AidlCameraDeviceCallbacks::onRepeatingRequestError(
+ int64_t lastFrameNumber,
+ int32_t repeatingRequestId) {
+ auto ret =
+ mBase->onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onRepeatingRequestError")
+ return binder::Status::ok();
+}
+
+binder::Status AidlCameraDeviceCallbacks::onRequestQueueEmpty() {
+ // not implemented
+ return binder::Status::ok();
+}
+
+status_t AidlCameraDeviceCallbacks::linkToDeath(const sp<DeathRecipient>& recipient,
+ void* cookie, uint32_t flags) {
+ return mDeathPipe.linkToDeath(recipient, cookie, flags);
+}
+status_t AidlCameraDeviceCallbacks::unlinkToDeath(const wp<DeathRecipient>& recipient,
+ void* cookie,
+ uint32_t flags,
+ wp<DeathRecipient>* outRecipient) {
+ return mDeathPipe.unlinkToDeath(recipient, cookie, flags, outRecipient);
+}
+
+} // namespace android::frameworks::cameraservice::device::implementation
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h
new file mode 100644
index 0000000..5cff5b3
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICECALLBACKS_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICECALLBACKS_H_
+
+#include <CameraService.h>
+#include <aidl/DeathPipe.h>
+#include <aidl/android/frameworks/cameraservice/device/BnCameraDeviceCallback.h>
+#include <aidl/android/frameworks/cameraservice/device/CaptureMetadataInfo.h>
+#include <aidl/android/frameworks/cameraservice/device/PhysicalCaptureResultInfo.h>
+#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
+#include <fmq/AidlMessageQueue.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <mutex>
+#include <thread>
+#include <utility>
+
+namespace android::frameworks::cameraservice::device::implementation {
+
+// VNDK classes
+using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
+using SICameraDeviceCallback =
+ ::aidl::android::frameworks::cameraservice::device::ICameraDeviceCallback;
+// NDK classes
+using UBnCameraDeviceCallbacks = ::android::hardware::camera2::BnCameraDeviceCallbacks;
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::frameworks::cameraservice::utils::DeathPipe;
+using ::android::hardware::camera2::impl::CameraMetadataNative;
+
+using CaptureResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+class AidlCameraDeviceCallbacks : public UBnCameraDeviceCallbacks {
+ public:
+ explicit AidlCameraDeviceCallbacks(const std::shared_ptr<SICameraDeviceCallback>& base);
+
+ ~AidlCameraDeviceCallbacks() override;
+
+ bool initializeLooper(int vndkVersion);
+
+ binder::Status onDeviceError(int32_t errorCode,
+ const CaptureResultExtras& resultExtras) override;
+
+ binder::Status onDeviceIdle() override;
+
+ binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
+ int64_t timestamp) override;
+
+ binder::Status onResultReceived(
+ const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
+ const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;
+
+ binder::Status onPrepared(int32_t streamId) override;
+
+ binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
+ int32_t repeatingRequestId) override;
+
+ binder::Status onRequestQueueEmpty() override;
+
+ status_t linkToDeath(const sp<DeathRecipient>& recipient, void* cookie,
+ uint32_t flags) override;
+ status_t unlinkToDeath(const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+ wp<DeathRecipient>* outRecipient) override;
+
+ void setCaptureResultMetadataQueue(std::shared_ptr<CaptureResultMetadataQueue> metadataQueue) {
+ mCaptureResultMetadataQueue = std::move(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,
+ CaptureResultExtras resultExtras,
+ std::vector<PhysicalCaptureResultInfo> physicalCaptureResultInfos) :
+ // TODO: make this std::movable
+ mResult(result),
+ mResultExtras(std::move(resultExtras)),
+ mPhysicalCaptureResultInfos(std::move(physicalCaptureResultInfos)) { }
+ };
+
+ struct CallbackHandler : public AHandler {
+ public:
+ void onMessageReceived(const sp<AMessage> &msg) override;
+ CallbackHandler(AidlCameraDeviceCallbacks *converter, int vndkVersion) :
+ mConverter(converter), mVndkVersion(vndkVersion) { }
+ private:
+ void processResultMessage(sp<ResultWrapper> &resultWrapper);
+ wp<AidlCameraDeviceCallbacks> mConverter = nullptr;
+ int mVndkVersion = -1;
+ };
+
+ void convertResultMetadataToAidl(const camera_metadata * src, SCaptureMetadataInfo * dst);
+ enum {
+ kWhatResultReceived,
+ };
+
+ static const char *kResultKey;
+
+ private:
+ std::shared_ptr<SICameraDeviceCallback> mBase;
+ std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+ sp<CallbackHandler> mHandler = nullptr;
+ sp<ALooper> mCbLooper = nullptr;
+
+ // Pipes death subscription from current NDK interface to VNDK mBase.
+ // Should consume calls to linkToDeath and unlinkToDeath.
+ DeathPipe mDeathPipe;
+};
+
+} // namespace android::frameworks::cameraservice::device::implementation
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICECALLBACKS_H_
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp
new file mode 100644
index 0000000..402f8a2
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "AidlCameraDeviceUser"
+
+#include "AidlCameraDeviceUser.h"
+#include <aidl/AidlUtils.h>
+#include <aidl/android/frameworks/cameraservice/device/CaptureMetadataInfo.h>
+#include <android-base/properties.h>
+
+namespace android::frameworks::cameraservice::device::implementation {
+
+// VNDK classes
+using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
+// NDK classes
+using UOutputConfiguration = ::android::hardware::camera2::params::OutputConfiguration;
+using USessionConfiguration = ::android::hardware::camera2::params::SessionConfiguration;
+using UStatus = ::android::binder::Status;
+using USubmitInfo = ::android::hardware::camera2::utils::SubmitInfo;
+
+using ::android::CameraMetadata;
+using ::android::hardware::cameraservice::utils::conversion::aidl::cloneFromAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::convertFromAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
+using ::ndk::ScopedAStatus;
+
+namespace {
+constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
+constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
+
+inline ScopedAStatus fromSStatus(const SStatus& s) {
+ return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
+ : ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(s));
+}
+inline ScopedAStatus fromUStatus(const UStatus& status) {
+ return status.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(status));
+}
+} // anonymous namespace
+
+AidlCameraDeviceUser::AidlCameraDeviceUser(const sp<UICameraDeviceUser>& deviceRemote):
+ mDeviceRemote(deviceRemote) {
+ mInitSuccess = initDevice();
+ mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
+}
+
+bool AidlCameraDeviceUser::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;
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::getCaptureRequestMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+ if (mInitSuccess) {
+ *_aidl_return = mCaptureRequestMetadataQueue->dupeDesc();
+ }
+ return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+ if (mInitSuccess) {
+ *_aidl_return = mCaptureResultMetadataQueue->dupeDesc();
+ }
+ return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::prepare(int32_t in_streamId) {
+ UStatus ret = mDeviceRemote->prepare(in_streamId);
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::submitRequestList(
+ const std::vector<SCaptureRequest>& in_requestList, bool in_isRepeating,
+ SSubmitInfo* _aidl_return) {
+ USubmitInfo submitInfo;
+ std::vector<UCaptureRequest> requests;
+ for (const auto& req: in_requestList) {
+ requests.emplace_back();
+ if (!convertRequestFromAidl(req, &requests.back())) {
+ ALOGE("%s: Failed to convert AIDL CaptureRequest.", __FUNCTION__);
+ return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
+ }
+ }
+ UStatus ret = mDeviceRemote->submitRequestList(requests,
+ in_isRepeating, &submitInfo);
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed submitRequestList to cameraservice: %s",
+ __FUNCTION__, ret.toString8().string());
+ return fromUStatus(ret);
+ }
+ mRequestId = submitInfo.mRequestId;
+ convertToAidl(submitInfo, _aidl_return);
+ return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::cancelRepeatingRequest(int64_t* _aidl_return) {
+ UStatus ret = mDeviceRemote->cancelRequest(mRequestId, _aidl_return);
+ return fromUStatus(ret);
+}
+
+ScopedAStatus AidlCameraDeviceUser::beginConfigure() {
+ UStatus ret = mDeviceRemote->beginConfigure();
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::endConfigure(SStreamConfigurationMode in_operatingMode,
+ const SCameraMetadata& in_sessionParams,
+ int64_t in_startTimeNs) {
+ CameraMetadata metadata;
+ if (!cloneFromAidl(in_sessionParams, &metadata)) {
+ return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
+ }
+
+ std::vector<int32_t> offlineStreamIds;
+ UStatus ret = mDeviceRemote->endConfigure(convertFromAidl(in_operatingMode),
+ metadata, in_startTimeNs,
+ &offlineStreamIds);
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::createStream(
+ const SOutputConfiguration& in_outputConfiguration, int32_t* _aidl_return) {
+ UOutputConfiguration outputConfig = convertFromAidl(in_outputConfiguration);
+ int32_t newStreamId;
+ UStatus ret = mDeviceRemote->createStream(outputConfig, &newStreamId);
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed to create stream: %s", __FUNCTION__, ret.toString8().string());
+ }
+ *_aidl_return = newStreamId;
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::createDefaultRequest(STemplateId in_templateId,
+ SCameraMetadata* _aidl_return) {
+ CameraMetadata metadata;
+ UStatus ret = mDeviceRemote->createDefaultRequest(convertFromAidl(in_templateId),
+ &metadata);
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed to create default request: %s", __FUNCTION__, ret.toString8().string());
+ return fromUStatus(ret);
+ }
+
+ if (filterVndkKeys(mVndkVersion, metadata, /*isStatic*/false) != OK) {
+ ALOGE("%s: Unable to filter vndk metadata keys for version %d",
+ __FUNCTION__, mVndkVersion);
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+
+ const camera_metadata_t* rawMetadata = metadata.getAndLock();
+ cloneToAidl(rawMetadata, _aidl_return);
+ metadata.unlock(rawMetadata);
+ return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::waitUntilIdle() {
+ UStatus ret = mDeviceRemote->waitUntilIdle();
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::flush(int64_t* _aidl_return) {
+ UStatus ret = mDeviceRemote->flush(_aidl_return);
+ return fromUStatus(ret);
+}
+
+ndk::ScopedAStatus AidlCameraDeviceUser::updateOutputConfiguration(
+ int32_t in_streamId, const SOutputConfiguration& in_outputConfiguration) {
+ UOutputConfiguration outputConfig = convertFromAidl(in_outputConfiguration);
+ UStatus ret = mDeviceRemote->updateOutputConfiguration(in_streamId, outputConfig);
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed to update output config for stream id: %d: %s",
+ __FUNCTION__, in_streamId, ret.toString8().string());
+ }
+ return fromUStatus(ret);
+}
+ndk::ScopedAStatus AidlCameraDeviceUser::isSessionConfigurationSupported(
+ const SSessionConfiguration& in_sessionConfiguration, bool* _aidl_return) {
+ USessionConfiguration sessionConfig = convertFromAidl(in_sessionConfiguration);
+ UStatus ret = mDeviceRemote->isSessionConfigurationSupported(sessionConfig,
+ _aidl_return);
+ return fromUStatus(ret);
+}
+ndk::ScopedAStatus AidlCameraDeviceUser::deleteStream(int32_t in_streamId) {
+ UStatus ret = mDeviceRemote->deleteStream(in_streamId);
+ return fromUStatus(ret);
+}
+ndk::ScopedAStatus AidlCameraDeviceUser::disconnect() {
+ UStatus ret = mDeviceRemote->disconnect();
+ return fromUStatus(ret);
+}
+bool AidlCameraDeviceUser::convertRequestFromAidl(
+ const SCaptureRequest& src, UCaptureRequest* dst) {
+ dst->mIsReprocess = false;
+ for (const auto& streamAndWindowId : src.streamAndWindowIds) {
+ dst->mStreamIdxList.push_back(streamAndWindowId.streamId);
+ dst->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
+ }
+
+ return copyPhysicalCameraSettings(src.physicalCameraSettings,
+ &(dst->mPhysicalCameraSettings));
+}
+bool AidlCameraDeviceUser::copyPhysicalCameraSettings(
+ const std::vector<SPhysicalCameraSettings>& src,
+ std::vector<UCaptureRequest::PhysicalCameraSettings>* dst) {
+ bool converted = false;
+ for (auto &e : src) {
+ dst->emplace_back();
+ CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
+ dst->back();
+ physicalCameraSetting.id = e.id;
+
+ // 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.getTag() == SCaptureMetadataInfo::fmqMetadataSize) {
+ /**
+ * Get settings from the fmq.
+ */
+ SCameraMetadata settingsFmq;
+ int64_t metadataSize = e.settings.get<SCaptureMetadataInfo::fmqMetadataSize>();
+ settingsFmq.metadata.resize(metadataSize);
+ int8_t* metadataPtr = (int8_t*) settingsFmq.metadata.data();
+ bool read = mCaptureRequestMetadataQueue->read(metadataPtr,
+ metadataSize);
+ if (!read) {
+ ALOGE("%s capture request settings could't be read from fmq size", __FUNCTION__);
+ converted = false;
+ } else {
+ converted = cloneFromAidl(settingsFmq, &physicalCameraSetting.settings);
+ }
+ } else {
+ /**
+ * The settings metadata is contained in request settings field.
+ */
+ converted = cloneFromAidl(e.settings.get<SCaptureMetadataInfo::metadata>(),
+ &physicalCameraSetting.settings);
+ }
+ if (!converted) {
+ ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace android::frameworks::cameraservice::device::implementation
\ No newline at end of file
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h
new file mode 100644
index 0000000..8014951
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICEUSER_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICEUSER_H_
+
+#include <CameraService.h>
+#include <aidl/android/frameworks/cameraservice/common/Status.h>
+#include <aidl/android/frameworks/cameraservice/device/BnCameraDeviceUser.h>
+#include <aidl/android/frameworks/cameraservice/device/CameraMetadata.h>
+#include <aidl/android/frameworks/cameraservice/device/OutputConfiguration.h>
+#include <aidl/android/frameworks/cameraservice/device/PhysicalCameraSettings.h>
+#include <aidl/android/frameworks/cameraservice/device/SessionConfiguration.h>
+#include <aidl/android/frameworks/cameraservice/device/StreamConfigurationMode.h>
+#include <aidl/android/frameworks/cameraservice/device/SubmitInfo.h>
+#include <aidl/android/frameworks/cameraservice/device/TemplateId.h>
+#include <aidl/android/hardware/common/fmq/MQDescriptor.h>
+#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <fmq/AidlMessageQueue.h>
+#include <memory>
+
+namespace android::frameworks::cameraservice::device::implementation {
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using CaptureRequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+using CaptureResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+// Stable NDK classes
+using SBnCameraDeviceUser = ::aidl::android::frameworks::cameraservice::device::BnCameraDeviceUser;
+using SCameraMetadata = ::aidl::android::frameworks::cameraservice::device::CameraMetadata;
+using SCaptureRequest = ::aidl::android::frameworks::cameraservice::device::CaptureRequest;
+using SOutputConfiguration =
+ ::aidl::android::frameworks::cameraservice::device::OutputConfiguration;
+using SPhysicalCameraSettings =
+ ::aidl::android::frameworks::cameraservice::device::PhysicalCameraSettings;
+using SSessionConfiguration =
+ ::aidl::android::frameworks::cameraservice::device::SessionConfiguration;
+using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
+using SStreamConfigurationMode =
+ ::aidl::android::frameworks::cameraservice::device::StreamConfigurationMode;
+using SSubmitInfo = ::aidl::android::frameworks::cameraservice::device::SubmitInfo;
+using STemplateId = ::aidl::android::frameworks::cameraservice::device::TemplateId;
+// Unstable NDK classes
+using UCaptureRequest= ::android::hardware::camera2::CaptureRequest;
+using UICameraDeviceUser = ::android::hardware::camera2::ICameraDeviceUser;
+
+static constexpr int32_t REQUEST_ID_NONE = -1;
+
+class AidlCameraDeviceUser final : public SBnCameraDeviceUser {
+ public:
+ explicit AidlCameraDeviceUser(const sp<UICameraDeviceUser> &deviceRemote);
+ ~AidlCameraDeviceUser() override = default;
+
+ ndk::ScopedAStatus beginConfigure() override;
+ ndk::ScopedAStatus cancelRepeatingRequest(int64_t* _aidl_return) override;
+ ndk::ScopedAStatus createDefaultRequest(STemplateId in_templateId,
+ SCameraMetadata* _aidl_return) override;
+ ndk::ScopedAStatus createStream(const SOutputConfiguration& in_outputConfiguration,
+ int32_t* _aidl_return) override;
+ ndk::ScopedAStatus deleteStream(int32_t in_streamId) override;
+ ndk::ScopedAStatus disconnect() override;
+ ndk::ScopedAStatus endConfigure(SStreamConfigurationMode in_operatingMode,
+ const SCameraMetadata& in_sessionParams,
+ int64_t in_startTimeNs) override;
+ ndk::ScopedAStatus flush(int64_t* _aidl_return) override;
+ ndk::ScopedAStatus getCaptureRequestMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+ ndk::ScopedAStatus getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+ ndk::ScopedAStatus isSessionConfigurationSupported(
+ const SSessionConfiguration& in_sessionConfiguration, bool* _aidl_return) override;
+ ndk::ScopedAStatus prepare(int32_t in_streamId) override;
+ ndk::ScopedAStatus submitRequestList(const std::vector<SCaptureRequest>& in_requestList,
+ bool in_isRepeating, SSubmitInfo* _aidl_return) override;
+ ndk::ScopedAStatus updateOutputConfiguration(
+ int32_t in_streamId, const SOutputConfiguration& in_outputConfiguration) override;
+ ndk::ScopedAStatus waitUntilIdle() override;
+
+ [[nodiscard]] bool initStatus() const { return mInitSuccess; }
+
+ std::shared_ptr<CaptureResultMetadataQueue> getCaptureResultMetadataQueue() {
+ return mCaptureResultMetadataQueue;
+ }
+
+ private:
+ bool initDevice();
+
+ bool convertRequestFromAidl(const SCaptureRequest &src, UCaptureRequest *dst);
+ bool copyPhysicalCameraSettings(const std::vector<SPhysicalCameraSettings> &src,
+ std::vector<CaptureRequest::PhysicalCameraSettings> *dst);
+
+ const sp<UICameraDeviceUser> mDeviceRemote;
+ std::unique_ptr<CaptureRequestMetadataQueue> mCaptureRequestMetadataQueue = nullptr;
+ std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
+ bool mInitSuccess = false;
+ int32_t mRequestId = REQUEST_ID_NONE;
+ int mVndkVersion = -1;
+};
+
+} // namespace android::frameworks::cameraservice::device::implementation
+
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERADEVICEUSER_H_
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.cpp b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
new file mode 100644
index 0000000..a62f6de
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "AidlCameraService"
+
+#include "AidlCameraService.h"
+#include <aidl/AidlCameraDeviceCallbacks.h>
+#include <aidl/AidlCameraDeviceUser.h>
+#include <aidl/AidlCameraServiceListener.h>
+#include <aidl/AidlUtils.h>
+#include <aidl/android/frameworks/cameraservice/common/CameraMetadataType.h>
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <binder/Status.h>
+#include <hidl/HidlTransportSupport.h>
+
+namespace android::frameworks::cameraservice::service::implementation {
+
+using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceCallbacks;
+using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceUser;
+using ::android::hardware::cameraservice::utils::conversion::aidl::areBindersEqual;
+using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
+using ::ndk::ScopedAStatus;
+
+// VNDK classes
+using SCameraMetadataType = ::aidl::android::frameworks::cameraservice::common::CameraMetadataType;
+using SVendorTag = ::aidl::android::frameworks::cameraservice::common::VendorTag;
+using SVendorTagSection = ::aidl::android::frameworks::cameraservice::common::VendorTagSection;
+// NDK classes
+using UICameraService = ::android::hardware::ICameraService;
+using UStatus = ::android::binder::Status;
+
+namespace {
+inline ScopedAStatus fromSStatus(const SStatus& s) {
+ return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
+ : ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(s));
+}
+inline ScopedAStatus fromUStatus(const UStatus& s) {
+ return s.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(s));
+}
+} // anonymous namespace
+
+std::shared_ptr<AidlCameraService> kCameraService;
+
+bool AidlCameraService::registerService(::android::CameraService* cameraService) {
+ kCameraService = SharedRefBase::make<AidlCameraService>(cameraService);
+ std::string serviceName = SBnCameraService::descriptor;
+ serviceName += "/default";
+ bool isDeclared = AServiceManager_isDeclared(serviceName.c_str());
+ if (!isDeclared) {
+ ALOGI("%s: AIDL vndk not declared.", __FUNCTION__);
+ return false;
+ }
+
+ binder_exception_t registered = AServiceManager_addService(
+ kCameraService->asBinder().get(), serviceName.c_str());
+ ALOGE_IF(registered != EX_NONE,
+ "%s: AIDL VNDK declared, but failed to register service: %d",
+ __FUNCTION__, registered);
+ return registered == EX_NONE;
+}
+
+AidlCameraService::AidlCameraService(::android::CameraService* cameraService):
+ mCameraService(cameraService) {
+ mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
+}
+ScopedAStatus AidlCameraService::getCameraCharacteristics(const std::string& in_cameraId,
+ SCameraMetadata* _aidl_return) {
+ if (_aidl_return == nullptr) { return fromSStatus(SStatus::ILLEGAL_ARGUMENT); }
+
+ ::android::CameraMetadata cameraMetadata;
+ UStatus ret = mCameraService->getCameraCharacteristics(in_cameraId,
+ mVndkVersion,
+ /* overrideToPortrait= */ false,
+ &cameraMetadata);
+ if (!ret.isOk()) {
+ if (ret.exceptionCode() != EX_SERVICE_SPECIFIC) {
+ ALOGE("%s: Transaction error when getting camera characteristics"
+ " from camera service: %d.",
+ __FUNCTION__ , ret.exceptionCode());
+ return fromUStatus(ret);
+ }
+ switch (ret.serviceSpecificErrorCode()) {
+ case UICameraService::ERROR_ILLEGAL_ARGUMENT:
+ ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, in_cameraId.c_str());
+ return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
+ default:
+ ALOGE("Get camera characteristics from camera service failed: %s",
+ ret.toString8().string());
+ return fromUStatus(ret);
+ }
+ }
+
+ if (filterVndkKeys(mVndkVersion, cameraMetadata) != OK) {
+ ALOGE("%s: Unable to filter vndk metadata keys for version %d",
+ __FUNCTION__, mVndkVersion);
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+
+ const camera_metadata_t* rawMetadata = cameraMetadata.getAndLock();
+ cloneToAidl(rawMetadata, _aidl_return);
+ cameraMetadata.unlock(rawMetadata);
+
+ return ScopedAStatus::ok();
+}
+ndk::ScopedAStatus AidlCameraService::connectDevice(
+ const std::shared_ptr<SICameraDeviceCallback>& in_callback,
+ const std::string& in_cameraId,
+ std::shared_ptr<SICameraDeviceUser>* _aidl_return) {
+ // Here, we first get NDK ICameraDeviceUser from mCameraService, then save
+ // that interface in the newly created AidlCameraDeviceUser impl class.
+ if (mCameraService == nullptr) {
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+ sp<hardware::camera2::ICameraDeviceUser> unstableDevice = nullptr;
+ // Create a hardware::camera2::ICameraDeviceCallback object which internally
+ // calls callback functions passed through hCallback.
+ sp<AidlCameraDeviceCallbacks> hybridCallbacks = new AidlCameraDeviceCallbacks(in_callback);
+ if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
+ ALOGE("Unable to handle callbacks on device, cannot connect");
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+ sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
+ binder::Status serviceRet = mCameraService->connectDevice(
+ callbacks,
+ in_cameraId,
+ std::string(),
+ /* clientFeatureId= */{},
+ hardware::ICameraService::USE_CALLING_UID,
+ /* scoreOffset= */ 0,
+ /* targetSdkVersion= */ __ANDROID_API_FUTURE__,
+ /* overrideToPortrait= */ false,
+ &unstableDevice);
+ if (!serviceRet.isOk()) {
+ ALOGE("%s: Unable to connect to camera device: %s", __FUNCTION__,
+ serviceRet.toString8().c_str());
+ return fromUStatus(serviceRet);
+ }
+
+ // Now we create a AidlCameraDeviceUser class, store the unstableDevice in it,
+ // and return that back. All calls on that interface will be forwarded to
+ // the NDK AIDL interface.
+ std::shared_ptr<AidlCameraDeviceUser> stableDevice =
+ ndk::SharedRefBase::make<AidlCameraDeviceUser>(unstableDevice);
+ if (!stableDevice->initStatus()) {
+ ALOGE("%s: Unable to initialize camera device AIDL wrapper", __FUNCTION__);
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+ hybridCallbacks->setCaptureResultMetadataQueue(
+ stableDevice->getCaptureResultMetadataQueue());
+ *_aidl_return = stableDevice;
+ return ScopedAStatus::ok();
+}
+void AidlCameraService::addToListenerCacheLocked(
+ std::shared_ptr<SICameraServiceListener> stableCsListener,
+ sp<UICameraServiceListener> csListener) {
+ mListeners.emplace_back(std::make_pair(stableCsListener, csListener));
+}
+sp<UICameraServiceListener> AidlCameraService::searchListenerCacheLocked(
+ const std::shared_ptr<SICameraServiceListener>& listener, bool removeIfFound) {
+ // Go through the mListeners list and compare the listener with the VNDK AIDL
+ // listener registered.
+ if (listener == nullptr) {
+ return nullptr;
+ }
+
+ auto it = mListeners.begin();
+ sp<UICameraServiceListener> csListener = nullptr;
+ for (;it != mListeners.end(); it++) {
+ if (areBindersEqual(listener->asBinder(), it->first->asBinder())) {
+ break;
+ }
+ }
+ if (it != mListeners.end()) {
+ csListener = it->second;
+ if (removeIfFound) {
+ mListeners.erase(it);
+ }
+ }
+ return csListener;
+}
+ndk::ScopedAStatus AidlCameraService::addListener(
+ const std::shared_ptr<SICameraServiceListener>& in_listener,
+ std::vector<SCameraStatusAndId>* _aidl_return) {
+ std::vector<hardware::CameraStatus> cameraStatusAndIds{};
+ SStatus status = addListenerInternal(
+ in_listener, &cameraStatusAndIds);
+ if (status != SStatus::NO_ERROR) {
+ return fromSStatus(status);
+ }
+
+ // Convert cameraStatusAndIds to VNDK AIDL
+ convertToAidl(cameraStatusAndIds, _aidl_return);
+ return ScopedAStatus::ok();
+}
+SStatus AidlCameraService::addListenerInternal(
+ const std::shared_ptr<SICameraServiceListener>& listener,
+ std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
+ if (mCameraService == nullptr) {
+ return SStatus::UNKNOWN_ERROR;
+ }
+ if (listener == nullptr || cameraStatusAndIds == nullptr) {
+ ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
+ return SStatus::ILLEGAL_ARGUMENT;
+ }
+ sp<UICameraServiceListener> csListener = nullptr;
+ // Check the cache for previously registered callbacks
+ {
+ Mutex::Autolock l(mListenerListLock);
+ csListener = searchListenerCacheLocked(listener);
+ if (csListener == nullptr) {
+ // Wrap a listener with AidlCameraServiceListener and pass it to
+ // CameraService.
+ csListener = sp<AidlCameraServiceListener>::make(listener);
+ // Add to cache
+ addToListenerCacheLocked(listener, csListener);
+ } else {
+ ALOGE("%s: Trying to add a listener %p already registered",
+ __FUNCTION__, listener.get());
+ return SStatus::ILLEGAL_ARGUMENT;
+ }
+ }
+ binder::Status serviceRet =
+ mCameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
+ if (!serviceRet.isOk()) {
+ ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
+ return convertToAidl(serviceRet);
+ }
+
+ cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(),
+ cameraStatusAndIds->end(),
+ [this](const hardware::CameraStatus& s) {
+ bool supportsHAL3 = false;
+ binder::Status sRet =
+ mCameraService->supportsCameraApi(s.cameraId,
+ UICameraService::API_VERSION_2, &supportsHAL3);
+ return !sRet.isOk() || !supportsHAL3;
+ }), cameraStatusAndIds->end());
+
+ return SStatus::NO_ERROR;
+}
+ndk::ScopedAStatus AidlCameraService::removeListener(
+ const std::shared_ptr<SICameraServiceListener>& in_listener) {
+ if (in_listener == nullptr) {
+ ALOGE("%s listener must not be NULL", __FUNCTION__);
+ return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
+ }
+ sp<UICameraServiceListener> csListener = nullptr;
+ {
+ Mutex::Autolock l(mListenerListLock);
+ csListener = searchListenerCacheLocked(in_listener, /*removeIfFound*/true);
+ }
+ if (csListener != nullptr) {
+ mCameraService->removeListener(csListener);
+ } else {
+ ALOGE("%s Removing unregistered listener %p", __FUNCTION__, in_listener.get());
+ return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
+ }
+ return ScopedAStatus::ok();
+}
+ndk::ScopedAStatus AidlCameraService::getCameraVendorTagSections(
+ std::vector<SProviderIdAndVendorTagSections>* _aidl_return) {
+ sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+ if (gCache == nullptr) {
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+
+ const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
+ &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
+ if (vendorIdsAndTagDescs.empty()) {
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+
+ std::vector<SProviderIdAndVendorTagSections>& tagIdAndVendorTagSections = *_aidl_return;
+ tagIdAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
+ size_t j = 0;
+ for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
+ std::vector<SVendorTagSection> vendorTagSections;
+ sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
+ const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
+ size_t numSections = sectionNames->size();
+ std::vector<std::vector<SVendorTag>> tagsBySection(numSections);
+ int tagCount = desc->getTagCount();
+ if (tagCount <= 0) {
+ continue;
+ }
+ std::vector<uint32_t> tags(tagCount);
+ desc->getTagArray(tags.data());
+ for (int i = 0; i < tagCount; i++) {
+ SVendorTag vt;
+ vt.tagId = tags[i];
+ vt.tagName = desc->getTagName(tags[i]);
+ vt.tagType = (SCameraMetadataType) desc->getTagType(tags[i]);
+ ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
+ tagsBySection[sectionIdx].push_back(vt);
+ }
+ vendorTagSections.resize(numSections);
+ for (size_t s = 0; s < numSections; s++) {
+ vendorTagSections[s].sectionName = (*sectionNames)[s].string();
+ vendorTagSections[s].tags = tagsBySection[s];
+ }
+ SProviderIdAndVendorTagSections & prvdrIdAndVendorTagSection =
+ tagIdAndVendorTagSections[j];
+ prvdrIdAndVendorTagSection.providerId = vendorIdAndTagDescs.first;
+ prvdrIdAndVendorTagSection.vendorTagSections = std::move(vendorTagSections);
+ j++;
+ }
+ return ScopedAStatus::ok();
+}
+
+} // namespace android::frameworks::cameraservice::service::implementation
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.h b/services/camera/libcameraservice/aidl/AidlCameraService.h
new file mode 100644
index 0000000..4c67ac7
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICE_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICE_H_
+
+#include <CameraService.h>
+#include <aidl/android/frameworks/cameraservice/common/Status.h>
+#include <aidl/android/frameworks/cameraservice/service/BnCameraService.h>
+
+namespace android::frameworks::cameraservice::service::implementation {
+
+// VNDK classes
+using SBnCameraService = ::aidl::android::frameworks::cameraservice::service::BnCameraService;
+using SCameraMetadata = ::aidl::android::frameworks::cameraservice::device::CameraMetadata;
+using SCameraStatusAndId = ::aidl::android::frameworks::cameraservice::service::CameraStatusAndId;
+using SICameraDeviceCallback =
+ ::aidl::android::frameworks::cameraservice::device::ICameraDeviceCallback;
+using SICameraDeviceUser = ::aidl::android::frameworks::cameraservice::device::ICameraDeviceUser;
+using SICameraServiceListener =
+ ::aidl::android::frameworks::cameraservice::service::ICameraServiceListener;
+using SProviderIdAndVendorTagSections =
+ ::aidl::android::frameworks::cameraservice::common::ProviderIdAndVendorTagSections;
+using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
+// NDK classes
+using UICameraServiceListener = ::android::hardware::ICameraServiceListener;
+
+class AidlCameraService: public SBnCameraService {
+ public:
+ static bool registerService(::android::CameraService* cameraService);
+
+ explicit AidlCameraService(::android::CameraService* cameraService);
+ ~AidlCameraService() override = default;
+ ndk::ScopedAStatus getCameraCharacteristics(const std::string& in_cameraId,
+ SCameraMetadata* _aidl_return) override;
+
+ ndk::ScopedAStatus connectDevice(const std::shared_ptr<SICameraDeviceCallback>& in_callback,
+ const std::string& in_cameraId,
+ std::shared_ptr<SICameraDeviceUser>* _aidl_return) override;
+
+ ndk::ScopedAStatus addListener(const std::shared_ptr<SICameraServiceListener>& in_listener,
+ std::vector<SCameraStatusAndId>* _aidl_return) override;
+
+ ndk::ScopedAStatus getCameraVendorTagSections(
+ std::vector<SProviderIdAndVendorTagSections>* _aidl_return) override;
+
+ ndk::ScopedAStatus removeListener(
+ const std::shared_ptr<SICameraServiceListener>& in_listener) override;
+
+ private:
+ void addToListenerCacheLocked(std::shared_ptr<SICameraServiceListener> stableCsListener,
+ sp<hardware::ICameraServiceListener> csListener);
+
+ sp<UICameraServiceListener> searchListenerCacheLocked(
+ const std::shared_ptr<SICameraServiceListener>& listener, bool removeIfFound = false);
+
+ SStatus addListenerInternal(const std::shared_ptr<SICameraServiceListener>& listener,
+ std::vector<hardware::CameraStatus>* cameraStatusAndIds);
+
+
+ ::android::CameraService* mCameraService;
+
+ Mutex mListenerListLock;
+ std::list<std::pair<std::shared_ptr<SICameraServiceListener>,
+ sp<UICameraServiceListener>>> mListeners;
+ int mVndkVersion = -1;
+
+};
+
+} // namespace android::frameworks::cameraservice::service::implementation
+
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICE_H_
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
new file mode 100644
index 0000000..d7ab0d9
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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 <aidl/AidlCameraServiceListener.h>
+#include <aidl/AidlUtils.h>
+#include <aidl/android/frameworks/cameraservice/common/Status.h>
+#include <aidl/android/frameworks/cameraservice/service/CameraStatusAndId.h>
+#include <camera/StringUtils.h>
+
+namespace android::frameworks::cameraservice::service::implementation {
+
+using ::android::hardware::cameraservice::utils::conversion::aidl::convertCameraStatusToAidl;
+// VNDK classes
+using SCameraStatusAndId = ::aidl::android::frameworks::cameraservice::service::CameraStatusAndId;
+using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
+
+binder::Status AidlCameraServiceListener::onStatusChanged(
+ int32_t status, const std::string& cameraId) {
+ SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
+ auto ret = mBase->onStatusChanged(sStatus, cameraId);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onStatusChanged")
+ return binder::Status::ok();
+}
+
+binder::Status AidlCameraServiceListener::onPhysicalCameraStatusChanged(
+ int32_t status, const std::string& cameraId,
+ const std::string& physicalCameraId) {
+ SCameraDeviceStatus sStatus = convertCameraStatusToAidl(status);
+
+ auto ret = mBase->onPhysicalCameraStatusChanged(sStatus, cameraId, physicalCameraId);
+ LOG_STATUS_ERROR_IF_NOT_OK(ret, "onPhysicalCameraStatusChanged")
+ return binder::Status::ok();
+}
+
+::android::binder::Status AidlCameraServiceListener::onTorchStatusChanged(
+ int32_t, const std::string&) {
+ // We don't implement onTorchStatusChanged
+ return binder::Status::ok();
+}
+
+::android::binder::Status AidlCameraServiceListener::onTorchStrengthLevelChanged(
+ const std::string&, int32_t) {
+ // We don't implement onTorchStrengthLevelChanged
+ return binder::Status::ok();
+}
+status_t AidlCameraServiceListener::linkToDeath(const sp<DeathRecipient>& recipient, void* cookie,
+ uint32_t flags) {
+ return mDeathPipe.linkToDeath(recipient, cookie, flags);
+}
+status_t AidlCameraServiceListener::unlinkToDeath(const wp<DeathRecipient>& recipient, void* cookie,
+ uint32_t flags,
+ wp<DeathRecipient>* outRecipient) {
+ return mDeathPipe.unlinkToDeath(recipient, cookie, flags, outRecipient);
+}
+
+} // namespace android::frameworks::cameraservice::service::implementation
diff --git a/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
new file mode 100644
index 0000000..6483fe1
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraServiceListener.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICELISTENER_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICELISTENER_H_
+
+
+#include <aidl/DeathPipe.h>
+#include <aidl/android/frameworks/cameraservice/service/CameraDeviceStatus.h>
+#include <aidl/android/frameworks/cameraservice/service/ICameraServiceListener.h>
+#include <android/hardware/BnCameraServiceListener.h>
+
+namespace android::frameworks::cameraservice::service::implementation {
+
+using ::android::frameworks::cameraservice::utils::DeathPipe;
+
+// VNDK classes
+using SCameraDeviceStatus = ::aidl::android::frameworks::cameraservice::service::CameraDeviceStatus;
+using SICameraServiceListener =
+ ::aidl::android::frameworks::cameraservice::service::ICameraServiceListener;
+// NDK classes
+using UBnCameraServiceListener = ::android::hardware::BnCameraServiceListener;
+
+/**
+ * A simple shim to pass calls from CameraService to VNDK client.
+ */
+class AidlCameraServiceListener : public UBnCameraServiceListener {
+ public:
+ AidlCameraServiceListener(const std::shared_ptr<SICameraServiceListener>& base):
+ mBase(base), mDeathPipe(this, base->asBinder()) {}
+
+ ~AidlCameraServiceListener() = default;
+
+ ::android::binder::Status onStatusChanged(int32_t status,
+ const std::string& cameraId) override;
+ ::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
+ const std::string& cameraId,
+ const std::string& physicalCameraId) override;
+
+ ::android::binder::Status onTorchStatusChanged(
+ int32_t status, const std::string& cameraId) override;
+ ::android::binder::Status onTorchStrengthLevelChanged(
+ const std::string& cameraId, int32_t newStrengthLevel) override;
+ binder::Status onCameraAccessPrioritiesChanged() override {
+ // TODO: no implementation yet.
+ return binder::Status::ok();
+ }
+ binder::Status onCameraOpened(const std::string& /*cameraId*/,
+ const std::string& /*clientPackageId*/) override {
+ // empty implementation
+ return binder::Status::ok();
+ }
+ binder::Status onCameraClosed(const std::string& /*cameraId*/) override {
+ // empty implementation
+ return binder::Status::ok();
+ }
+
+ status_t linkToDeath(const sp<DeathRecipient>& recipient, void* cookie,
+ uint32_t flags) override;
+ status_t unlinkToDeath(const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+ wp<DeathRecipient>* outRecipient) override;
+
+ private:
+ std::shared_ptr<SICameraServiceListener> mBase;
+
+ // Pipes death subscription to current NDK AIDL interface to VNDK mBase.
+ // Should consume calls to linkToDeath and unlinkToDeath.
+ DeathPipe mDeathPipe;
+};
+
+} // android
+
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLCAMERASERVICELISTENER_H_
\ No newline at end of file
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
new file mode 100644
index 0000000..7291c5f
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "AidlUtils"
+
+#include <aidl/AidlUtils.h>
+#include <aidl/VndkVersionMetadataTags.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <device3/Camera3StreamInterface.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <mediautils/AImageReaderUtils.h>
+#include <camera/StringUtils.h>
+
+namespace android::hardware::cameraservice::utils::conversion::aidl {
+
+using aimg::AImageReader_getHGBPFromHandle;
+using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
+
+// Note: existing data in dst will be gone. Caller still owns the memory of src
+void cloneToAidl(const camera_metadata_t* src, SCameraMetadata* dst) {
+ if (src == nullptr) {
+ ALOGW("%s:attempt to convert empty metadata to AIDL", __FUNCTION__);
+ return;
+ }
+ size_t size = get_camera_metadata_size(src);
+ uint8_t* startPtr = (uint8_t*)src;
+ uint8_t* endPtr = startPtr + size;
+ dst->metadata.assign(startPtr, endPtr);
+}
+
+// The camera metadata here is cloned. Since we're reading metadata over
+// the binder we would need to clone it in order to avoid alignment issues.
+bool cloneFromAidl(const SCameraMetadata &src, CameraMetadata *dst) {
+ const camera_metadata_t *buffer =
+ reinterpret_cast<const camera_metadata_t*>(src.metadata.data());
+ size_t expectedSize = src.metadata.size();
+ if (buffer != nullptr) {
+ int res = validate_camera_metadata_structure(buffer, &expectedSize);
+ if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ *dst = buffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ return false;
+ }
+ }
+ return true;
+}
+
+int32_t convertFromAidl(SStreamConfigurationMode streamConfigurationMode) {
+ switch (streamConfigurationMode) {
+ case SStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
+ return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE;
+ case SStreamConfigurationMode::NORMAL_MODE:
+ return camera2::ICameraDeviceUser::NORMAL_MODE;
+ default:
+ // TODO: Fix this
+ return camera2::ICameraDeviceUser::VENDOR_MODE_START;
+ }
+}
+
+UOutputConfiguration convertFromAidl(const SOutputConfiguration &src) {
+ std::vector<sp<IGraphicBufferProducer>> iGBPs;
+ auto &windowHandles = src.windowHandles;
+ iGBPs.reserve(windowHandles.size());
+
+ for (auto &handle : windowHandles) {
+ native_handle_t* nh = makeFromAidl(handle);
+ iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(nh)));
+ native_handle_delete(nh);
+ }
+ UOutputConfiguration outputConfiguration(
+ iGBPs, convertFromAidl(src.rotation), src.physicalCameraId,
+ src.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
+ (windowHandles.size() > 1));
+ return outputConfiguration;
+}
+
+USessionConfiguration convertFromAidl(const SSessionConfiguration &src) {
+ USessionConfiguration sessionConfig(src.inputWidth, src.inputHeight,
+ src.inputFormat, static_cast<int>(src.operationMode));
+
+ for (const auto& os : src.outputStreams) {
+ UOutputConfiguration config = convertFromAidl(os);
+ sessionConfig.addOutputConfiguration(config);
+ }
+
+ return sessionConfig;
+}
+
+int convertFromAidl(SOutputConfiguration::Rotation rotation) {
+ switch(rotation) {
+ case SOutputConfiguration::Rotation::R270:
+ return android::camera3::CAMERA_STREAM_ROTATION_270;
+ case SOutputConfiguration::Rotation::R180:
+ return android::camera3::CAMERA_STREAM_ROTATION_180;
+ case SOutputConfiguration::Rotation::R90:
+ return android::camera3::CAMERA_STREAM_ROTATION_90;
+ case SOutputConfiguration::Rotation::R0:
+ default:
+ return android::camera3::CAMERA_STREAM_ROTATION_0;
+ }
+}
+
+int32_t convertFromAidl(STemplateId templateId) {
+ switch(templateId) {
+ case STemplateId::PREVIEW:
+ return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW;
+ case STemplateId::STILL_CAPTURE:
+ return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE;
+ case STemplateId::RECORD:
+ return camera2::ICameraDeviceUser::TEMPLATE_RECORD;
+ case STemplateId::VIDEO_SNAPSHOT:
+ return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT;
+ case STemplateId::ZERO_SHUTTER_LAG:
+ return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG;
+ case STemplateId::MANUAL:
+ return camera2::ICameraDeviceUser::TEMPLATE_MANUAL;
+ }
+}
+
+void convertToAidl(const camera2::utils::SubmitInfo& submitInfo, SSubmitInfo* hSubmitInfo) {
+ hSubmitInfo->requestId = submitInfo.mRequestId;
+ hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber;
+}
+
+
+SStatus convertToAidl(const binder::Status &status) {
+ if (status.isOk()) {
+ return SStatus::NO_ERROR;
+ }
+ if (status.exceptionCode() != EX_SERVICE_SPECIFIC) {
+ return SStatus::UNKNOWN_ERROR;
+ }
+
+ switch (status.serviceSpecificErrorCode()) {
+ case hardware::ICameraService::ERROR_DISCONNECTED:
+ return SStatus::DISCONNECTED;
+ case hardware::ICameraService::ERROR_CAMERA_IN_USE:
+ return SStatus::CAMERA_IN_USE;
+ case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
+ return SStatus::MAX_CAMERAS_IN_USE;
+ case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
+ return SStatus::ILLEGAL_ARGUMENT;
+ case hardware::ICameraService::ERROR_DEPRECATED_HAL:
+ // Should not reach here since we filtered legacy HALs earlier
+ return SStatus::DEPRECATED_HAL;
+ case hardware::ICameraService::ERROR_DISABLED:
+ return SStatus::DISABLED;
+ case hardware::ICameraService::ERROR_PERMISSION_DENIED:
+ return SStatus::PERMISSION_DENIED;
+ case hardware::ICameraService::ERROR_INVALID_OPERATION:
+ return SStatus::INVALID_OPERATION;
+ default:
+ return SStatus::UNKNOWN_ERROR;
+ }
+}
+
+SCaptureResultExtras convertToAidl(const UCaptureResultExtras &src) {
+ SCaptureResultExtras dst;
+ dst.requestId = src.requestId;
+ dst.burstId = src.burstId;
+ dst.frameNumber = src.frameNumber;
+ dst.partialResultCount = src.partialResultCount;
+ dst.errorStreamId = src.errorStreamId;
+ dst.errorPhysicalCameraId = src.errorPhysicalCameraId;
+ return dst;
+}
+
+SErrorCode convertToAidl(int32_t errorCode) {
+ switch(errorCode) {
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED:
+ return SErrorCode::CAMERA_DISCONNECTED;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
+ return SErrorCode::CAMERA_DEVICE;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE:
+ return SErrorCode::CAMERA_SERVICE;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
+ return SErrorCode::CAMERA_REQUEST;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
+ return SErrorCode::CAMERA_RESULT;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
+ return SErrorCode::CAMERA_BUFFER;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED:
+ return SErrorCode::CAMERA_DISABLED;
+ case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR:
+ return SErrorCode::CAMERA_INVALID_ERROR;
+ default:
+ return SErrorCode::CAMERA_UNKNOWN_ERROR;
+ }
+}
+
+std::vector<SPhysicalCaptureResultInfo> convertToAidl(
+ const std::vector<UPhysicalCaptureResultInfo>& src,
+ std::shared_ptr<CaptureResultMetadataQueue>& fmq) {
+ std::vector<SPhysicalCaptureResultInfo> dst;
+ dst.resize(src.size());
+ size_t i = 0;
+ for (auto &physicalCaptureResultInfo : src) {
+ dst[i++] = convertToAidl(physicalCaptureResultInfo, fmq);
+ }
+ return dst;
+}
+
+SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo & src,
+ std::shared_ptr<CaptureResultMetadataQueue> & fmq) {
+ SPhysicalCaptureResultInfo dst;
+ dst.physicalCameraId = src.mPhysicalCameraId;
+
+ const camera_metadata_t *rawMetadata = src.mPhysicalCameraMetadata.getAndLock();
+ // Try using fmq at first.
+ size_t metadata_size = get_camera_metadata_size(rawMetadata);
+ if ((metadata_size > 0) && (fmq->availableToWrite() > 0)) {
+ if (fmq->write((int8_t *)rawMetadata, metadata_size)) {
+ dst.physicalCameraMetadata.set<SCaptureMetadataInfo::fmqMetadataSize>(metadata_size);
+ } else {
+ ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
+ SCameraMetadata metadata;
+ cloneToAidl(rawMetadata, &metadata);
+ dst.physicalCameraMetadata.set<SCaptureMetadataInfo::metadata>(std::move(metadata));
+ }
+ }
+ src.mPhysicalCameraMetadata.unlock(rawMetadata);
+ return dst;
+}
+
+void convertToAidl(const std::vector<hardware::CameraStatus> &src,
+ std::vector<SCameraStatusAndId>* dst) {
+ dst->resize(src.size());
+ size_t i = 0;
+ for (const auto &statusAndId : src) {
+ auto &a = (*dst)[i++];
+ a.cameraId = statusAndId.cameraId;
+ a.deviceStatus = convertCameraStatusToAidl(statusAndId.status);
+ size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
+ a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
+ for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
+ a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j];
+ }
+ }
+}
+
+SCameraDeviceStatus convertCameraStatusToAidl(int32_t src) {
+ SCameraDeviceStatus deviceStatus = SCameraDeviceStatus::STATUS_UNKNOWN;
+ switch(src) {
+ case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
+ deviceStatus = SCameraDeviceStatus::STATUS_NOT_PRESENT;
+ break;
+ case hardware::ICameraServiceListener::STATUS_PRESENT:
+ deviceStatus = SCameraDeviceStatus::STATUS_PRESENT;
+ break;
+ case hardware::ICameraServiceListener::STATUS_ENUMERATING:
+ deviceStatus = SCameraDeviceStatus::STATUS_ENUMERATING;
+ break;
+ case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
+ deviceStatus = SCameraDeviceStatus::STATUS_NOT_AVAILABLE;
+ break;
+ default:
+ break;
+ }
+ return deviceStatus;
+}
+
+bool areBindersEqual(const ndk::SpAIBinder& b1, const ndk::SpAIBinder& b2) {
+ return !AIBinder_lt(b1.get(), b2.get()) && !AIBinder_lt(b2.get(), b1.get());
+}
+
+status_t filterVndkKeys(int vndkVersion, CameraMetadata &metadata, bool isStatic) {
+ if (vndkVersion == __ANDROID_API_FUTURE__) {
+ // VNDK version in ro.vndk.version is a version code-name that
+ // corresponds to the current version.
+ return OK;
+ }
+ const auto &apiLevelToKeys =
+ isStatic ? static_api_level_to_keys : dynamic_api_level_to_keys;
+ // Find the vndk versions above the given vndk version. All the vndk
+ // versions above the given one, need to have their keys filtered from the
+ // metadata in order to avoid metadata invalidation.
+ auto it = apiLevelToKeys.upper_bound(vndkVersion);
+ while (it != apiLevelToKeys.end()) {
+ for (const auto &key : it->second) {
+ status_t res = metadata.erase(key);
+ if (res != OK) {
+ ALOGE("%s metadata key %d could not be erased", __FUNCTION__, key);
+ return res;
+ }
+ }
+ it++;
+ }
+ return OK;
+}
+
+} // namespace android::hardware::cameraservice::utils::conversion::aidl
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.h b/services/camera/libcameraservice/aidl/AidlUtils.h
new file mode 100644
index 0000000..c89d7ff
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlUtils.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLUTILS_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLUTILS_H_
+
+#include <aidl/android/frameworks/cameraservice/common/Status.h>
+#include <aidl/android/frameworks/cameraservice/device/CameraMetadata.h>
+#include <aidl/android/frameworks/cameraservice/device/CaptureResultExtras.h>
+#include <aidl/android/frameworks/cameraservice/device/ErrorCode.h>
+#include <aidl/android/frameworks/cameraservice/device/CaptureMetadataInfo.h>
+#include <aidl/android/frameworks/cameraservice/device/OutputConfiguration.h>
+#include <aidl/android/frameworks/cameraservice/device/PhysicalCaptureResultInfo.h>
+#include <aidl/android/frameworks/cameraservice/device/SessionConfiguration.h>
+#include <aidl/android/frameworks/cameraservice/device/StreamConfigurationMode.h>
+#include <aidl/android/frameworks/cameraservice/device/SubmitInfo.h>
+#include <aidl/android/frameworks/cameraservice/device/TemplateId.h>
+#include <aidl/android/frameworks/cameraservice/service/CameraDeviceStatus.h>
+#include <aidl/android/frameworks/cameraservice/service/CameraStatusAndId.h>
+#include <android/hardware/ICameraService.h>
+#include <android/hardware/camera2/ICameraDeviceUser.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+#include <camera/CameraMetadata.h>
+#include <fmq/AidlMessageQueue.h>
+#include <hardware/camera.h>
+
+namespace android::hardware::cameraservice::utils::conversion::aidl {
+
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::CameraMetadata;
+using CaptureResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+// VNDK classes
+using SCameraDeviceStatus = ::aidl::android::frameworks::cameraservice::service::CameraDeviceStatus;
+using SCameraMetadata = ::aidl::android::frameworks::cameraservice::device::CameraMetadata;
+using SCameraStatusAndId = ::aidl::android::frameworks::cameraservice::service::CameraStatusAndId;
+using SCaptureResultExtras =
+ ::aidl::android::frameworks::cameraservice::device::CaptureResultExtras;
+using SErrorCode = ::aidl::android::frameworks::cameraservice::device::ErrorCode;
+using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
+using SOutputConfiguration =
+ ::aidl::android::frameworks::cameraservice::device::OutputConfiguration;
+using SPhysicalCaptureResultInfo =
+ ::aidl::android::frameworks::cameraservice::device::PhysicalCaptureResultInfo;
+using SSessionConfiguration =
+ ::aidl::android::frameworks::cameraservice::device::SessionConfiguration;
+using SStatus = ::aidl::android::frameworks::cameraservice::common::Status;
+using SStreamConfigurationMode =
+ ::aidl::android::frameworks::cameraservice::device::StreamConfigurationMode;
+using SSubmitInfo = ::aidl::android::frameworks::cameraservice::device::SubmitInfo;
+using STemplateId = ::aidl::android::frameworks::cameraservice::device::TemplateId;
+// NDK classes
+using UCaptureResultExtras = ::android::hardware::camera2::impl::CaptureResultExtras;
+using UOutputConfiguration = ::android::hardware::camera2::params::OutputConfiguration;
+using UPhysicalCaptureResultInfo = ::android::hardware::camera2::impl::PhysicalCaptureResultInfo;
+using USessionConfiguration = ::android::hardware::camera2::params::SessionConfiguration;
+
+// Common macro to log errors returned from stable AIDL calls
+#define LOG_STATUS_ERROR_IF_NOT_OK(status, callName) \
+ if (!(status).isOk()) { \
+ if ((status).getExceptionCode() == EX_SERVICE_SPECIFIC) { \
+ SStatus errStatus = static_cast<SStatus>((status).getServiceSpecificError()); \
+ ALOGE("%s: %s callback failed: %s", __FUNCTION__, callName, \
+ toString(errStatus).c_str()); \
+ } else { \
+ ALOGE("%s: Transaction failed during %s: %d", __FUNCTION__, callName, \
+ (status).getExceptionCode()); \
+ } \
+ }
+
+// Note: existing data in dst will be gone. Caller still owns the memory of src
+void cloneToAidl(const camera_metadata_t *src, SCameraMetadata* dst);
+
+bool cloneFromAidl(const SCameraMetadata &src, CameraMetadata *dst);
+
+int32_t convertFromAidl(SStreamConfigurationMode streamConfigurationMode);
+
+UOutputConfiguration convertFromAidl(const SOutputConfiguration &src);
+
+USessionConfiguration convertFromAidl(const SSessionConfiguration &src);
+
+int convertFromAidl(SOutputConfiguration::Rotation rotation);
+
+int32_t convertFromAidl(STemplateId templateId);
+
+void convertToAidl(const hardware::camera2::utils::SubmitInfo &submitInfo,
+ SSubmitInfo *hSubmitInfo);
+
+SStatus convertToAidl(const binder::Status &status);
+
+SCaptureResultExtras convertToAidl(const UCaptureResultExtras &captureResultExtras);
+
+SErrorCode convertToAidl(int32_t errorCode);
+
+std::vector<SPhysicalCaptureResultInfo> convertToAidl(
+ const std::vector<UPhysicalCaptureResultInfo>& src,
+ std::shared_ptr<CaptureResultMetadataQueue>& fmq);
+
+SPhysicalCaptureResultInfo convertToAidl(const UPhysicalCaptureResultInfo& src,
+ std::shared_ptr<CaptureResultMetadataQueue>& fmq);
+
+void convertToAidl(const std::vector<hardware::CameraStatus> &src,
+ std::vector<SCameraStatusAndId>* dst);
+
+SCameraDeviceStatus convertCameraStatusToAidl(int32_t src);
+
+bool areBindersEqual(const ndk::SpAIBinder& b1, const ndk::SpAIBinder& b2);
+
+status_t filterVndkKeys(int vndkVersion, CameraMetadata &metadata, bool isStatic = true);
+
+} // namespace android::hardware::cameraservice::utils::conversion::aidl
+
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLUTILS_H_
diff --git a/services/camera/libcameraservice/aidl/DeathPipe.cpp b/services/camera/libcameraservice/aidl/DeathPipe.cpp
new file mode 100644
index 0000000..de46411
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/DeathPipe.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "DeathPipe"
+
+#include "DeathPipe.h"
+
+namespace android::frameworks::cameraservice::utils {
+
+DeathPipe::DeathPipe(IBinder* parent, const ::ndk::SpAIBinder& binder):
+ mParent(parent), mAIBinder(binder) {
+ mDeathRecipient = ::ndk::ScopedAIBinder_DeathRecipient(
+ AIBinder_DeathRecipient_new(DeathPipe::onDeathCallback));
+ // Set an unlinked callback that allows Obituaries to be deallocated
+ AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(),
+ DeathPipe::onUnlinkedCallback);
+}
+
+status_t DeathPipe::linkToDeath(const sp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags) {
+ LOG_ALWAYS_FATAL_IF(recipient == nullptr, "%s: recipient must be non-nullptr", __FUNCTION__);
+ std::lock_guard<std::mutex> _l(mLock);
+
+ // Create and immortalize an obituary before linking it to death.
+ // The created Obituary can now only be garbage collected if it is unlinked from death
+ std::shared_ptr<Obituary> obituary = std::make_shared<Obituary>(recipient, cookie,
+ flags, /* who= */ mParent);
+ obituary->immortalize();
+
+ // Ensure that "cookie" is a pointer to an immortal obituary.
+ // AIBinder_linkToDeath calls DeathPipe::onUnlinkedCallback if linking to death fails, marking
+ // it for garbage collection
+ binder_status_t ret = AIBinder_linkToDeath(mAIBinder.get(),
+ mDeathRecipient.get(),
+ /* cookie= */ obituary.get());
+ if (ret != STATUS_OK) {
+ return DEAD_OBJECT;
+ }
+ mObituaries.emplace_back(obituary);
+ return NO_ERROR;
+}
+
+status_t DeathPipe::unlinkToDeath(const wp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags,
+ wp<IBinder::DeathRecipient>* outRecipient) {
+ std::lock_guard<std::mutex> _l(mLock);
+ // Temporary Obituary for checking equality
+ std::shared_ptr<Obituary> inObituary = std::make_shared<Obituary>(recipient, cookie,
+ flags, mParent);
+ for (auto it = mObituaries.begin(); it != mObituaries.end(); it++) {
+ if ((*inObituary) == (**it)) {
+ if (outRecipient != nullptr) {
+ *outRecipient = (*it)->recipient;
+ }
+ // Unlink the found Obituary from death. AIBinder_unlinkToDeath calls
+ // DeathPipe::onUnlinkedCallback with the given cookie when unlinking is done
+ binder_status_t ret = AIBinder_unlinkToDeath(mAIBinder.get(),
+ mDeathRecipient.get(),
+ /* cookie= */ (*it).get());
+ mObituaries.erase(it);
+ return ret == STATUS_OK ? NO_ERROR : DEAD_OBJECT;
+ }
+ }
+ return NAME_NOT_FOUND;
+}
+
+DeathPipe::~DeathPipe() = default;
+
+
+void DeathPipe::onDeathCallback(void* cookie) {
+ // Cookie will always be a pointer to a valid immortal Obituary
+ Obituary* obituary = static_cast<Obituary*>(cookie);
+ obituary->onDeath();
+ // Don't call Obituary::clear() because VNDK Binder will call DeathPipe::onUnlinkedCallback()
+ // when it is ready
+}
+
+void DeathPipe::onUnlinkedCallback(void* cookie) {
+ // Cookie will always be a pointer to a valid immortal Obituary.
+ Obituary* obituary = static_cast<Obituary*>(cookie);
+ // Mark obituary to be garbage collected if needed. onDeathCallback won't be called with
+ // this particular cookie after this.
+ obituary->clear();
+}
+
+} // namespace android::frameworks::cameraservice::utils
\ No newline at end of file
diff --git a/services/camera/libcameraservice/aidl/DeathPipe.h b/services/camera/libcameraservice/aidl/DeathPipe.h
new file mode 100644
index 0000000..a816dd0
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/DeathPipe.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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 FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
+#define FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+#include <binder/Parcel.h>
+#include <list>
+
+namespace android::frameworks::cameraservice::utils {
+
+/**
+ * This is a helper class to pipe death notifications from VNDK {@code AIBinder} to
+ * S/NDK {@code IBinder}.
+ *
+ * To use this class, create a DeathPipe member object as a field of NDK interface
+ * implementation, and forward functions {@code BBinder::linkToDeath} and
+ * {@code BBinder::unlinkToDeath} to corresponding DeathPipe functions.
+ */
+class DeathPipe {
+ public:
+ /**
+ * @param parent the NDK Binder object. Assumed to live longer than the DeathPipe
+ * object
+ * @param binder the VNDK Binder object which DeathPipe with subscribe to.
+ */
+ explicit DeathPipe(IBinder* parent, const ::ndk::SpAIBinder& binder);
+ ~DeathPipe();
+
+ status_t linkToDeath(const sp<IBinder::DeathRecipient>& recipient, void* cookie,
+ uint32_t flags);
+ status_t unlinkToDeath(const wp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags, wp<IBinder::DeathRecipient>* outRecipient);
+
+ // Static functions that will be called by VNDK binder upon death or unlinking
+ static void onDeathCallback(void* cookie);
+ static void onUnlinkedCallback(void* cookie);
+
+ private:
+ /**
+ * {@code Obituary} is a tiny container that contains some metadata to pass VNDK binder's
+ * death notification to the NDK binder. A pointer to the Obituary is used as the
+ * {@code cookie} in VNDK binder's death notification.
+ *
+ * Theoretically, the VNDK binder might send out death notification after the DeathPipe
+ * object is destroyed, so care must be taken to ensure that Obituaries aren't accidentally
+ * destroyed before VNDK binder stops using its cookies.
+ *
+ */
+ struct Obituary: public std::enable_shared_from_this<Obituary> {
+ wp<IBinder::DeathRecipient> recipient; // NDK death recipient
+ void *cookie; // cookie sent by the NDK recipient
+ uint32_t flags; // flags sent by the NDK recipient
+ wp<IBinder> who; // NDK binder whose death 'recipient' subscribed to
+
+ // Self ptr to ensure we don't destroy this obituary while it can still be notified by the
+ // VNDK Binder. When populated with Obituary::immortalize, this Obituary won't be
+ // garbage collected until Obituary::clear is called.
+ std::shared_ptr<Obituary> mSelfPtr;
+
+ Obituary(const wp<IBinder::DeathRecipient>& recipient, void* cookie,
+ uint32_t flags, IBinder* who) :
+ recipient(recipient), cookie(cookie), flags(flags),
+ who(who), mSelfPtr(nullptr) {}
+
+ // Function to be called when the VNDK Binder dies. Pipes the notification to the relevant
+ // NDK recipient if it still exists
+ void onDeath() const {
+ sp<IBinder::DeathRecipient> r = recipient.promote();
+ if (r == nullptr) { return; }
+ r->binderDied(who);
+ };
+
+ // Should be called before calling AIBinder_linkToDeath. Once this function returns this
+ // Obituary won't be garbage collected until Obituary::clear is called.
+ void immortalize() {
+ mSelfPtr = shared_from_this();
+ }
+
+ // Should be called when this Obituary can be garbage collected.
+ // Typically, after the Obituary is no longer linked to a VNDK DeathRecipient
+ void clear() {
+ mSelfPtr = nullptr;
+ }
+
+ bool operator==(const Obituary& rhs) const {
+ return recipient == rhs.recipient &&
+ cookie == rhs.cookie &&
+ flags == rhs.flags &&
+ who == rhs.who;
+ }
+ };
+
+ // Parent to which the cameraservice wants to subscribe to for death notification
+ IBinder* mParent;
+
+ // VNDK Binder object to which the death notification will be bound to. If it dies,
+ // cameraservice will be notified as if mParent died.
+ ::ndk::SpAIBinder mAIBinder;
+
+ // Owning VNDK's deathRecipient ensures that all linked death notifications are cleaned up
+ // when this class destructs.
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+ // Lock to protect access to fields below.
+ std::mutex mLock;
+ // List of all obituaries created by DeathPipe, used to unlink death subscription
+ std::list<std::shared_ptr<Obituary>> mObituaries;
+
+};
+
+} // namespace android::frameworks::cameraservice::utils
+
+#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_DEATHPIPE_H_
diff --git a/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
new file mode 100644
index 0000000..48c804d
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 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 <map>
+#include <vector>
+#pragma once
+/**
+ * ! Do not edit this file directly !
+ *
+ * Generated automatically from vndk_camera_metadata_tags.mako. To be included in libcameraservice
+ * only by aidl/AidlUtils.cpp.
+ */
+
+/**
+ * API level to static keys mapping. To be used for filtering out keys depending on vndk version
+ * used by vendor clients.
+ */
+std::map<int, std::vector<camera_metadata_tag>> static_api_level_to_keys{
+ {30, {
+ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES,
+ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES,
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE,
+ ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES,
+ } },
+ {31, {
+ ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION,
+ ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE,
+ ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED,
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_INFO_BINNING_FACTOR,
+ ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
+ } },
+ {32, {
+ ANDROID_INFO_DEVICE_STATE_ORIENTATIONS,
+ } },
+ {33, {
+ ANDROID_AUTOMOTIVE_LENS_FACING,
+ ANDROID_AUTOMOTIVE_LOCATION,
+ ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
+ ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+ ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+ ANDROID_SENSOR_READOUT_TIMESTAMP,
+ } },
+ {34, {
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+ } },
+};
+
+/**
+ * API level to dynamic keys mapping. To be used for filtering out keys depending on vndk version
+ * used by vendor clients.
+ */
+std::map<int, std::vector<camera_metadata_tag>> dynamic_api_level_to_keys{
+ {30, {
+ ANDROID_CONTROL_EXTENDED_SCENE_MODE,
+ ANDROID_CONTROL_ZOOM_RATIO,
+ ANDROID_SCALER_ROTATE_AND_CROP,
+ } },
+ {31, {
+ ANDROID_SENSOR_PIXEL_MODE,
+ ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+ } },
+ {34, {
+ ANDROID_CONTROL_AUTOFRAMING,
+ ANDROID_CONTROL_AUTOFRAMING_STATE,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE,
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+ ANDROID_EXTENSION_CURRENT_TYPE,
+ ANDROID_EXTENSION_STRENGTH,
+ ANDROID_SCALER_RAW_CROP_REGION,
+ } },
+};