cameraservice: Add AIDL vndk client support

With HIDL being deprecated, vndk camera clients were moved to stable
AIDL interfaces. This CL adds support for AIDL vndk clients to the
cameraservice. It leaves in support for HIDL vndk clients as vendor
partition might not be updated with the system partition.

As of this CL, cameraservice supports both AIDL vndk clients and HIDL
VNDK clients. Specifically, this CL creates a new cameraservice
endpoint for AIDL vndk clients to interact with and creates a thin
shim that translates vndk AIDL data structures to ndk AIDL data
structures before passing it to main cameraservice logic.

Bug: 243593375
Test: Migrating VTS test in a future CL
Change-Id: Iaf7a434650d5f95149ccb7fcbf1a134852d6f71c
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
new file mode 100644
index 0000000..4c6d6f6
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceCallbacks.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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) {
+    // not implemented
+    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