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