Add AidlProviderInfo to handle aidl hal providers.

Bug: 196432585

Test: GCA; Record videos and take pictures (Basic validity)
Test: Camera CTS with AIDL provider
Test: Use Camera VNDK

Change-Id: I8c2bf49100c45d5f09f6ef97a0d5739ebc2199d7
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 6d884cb..22bb234 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -43,6 +43,7 @@
         "android.hardware.camera.provider@2.5",
         "android.hardware.camera.provider@2.6",
         "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V1-ndk",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 8428881..8cda830 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -49,6 +49,7 @@
         "common/CameraProviderManager.cpp",
         "common/FrameProcessorBase.cpp",
         "common/hidl/HidlProviderInfo.cpp",
+        "common/aidl/AidlProviderInfo.cpp",
         "api1/Camera2Client.cpp",
         "api1/client2/Parameters.cpp",
         "api1/client2/FrameProcessor.cpp",
@@ -115,6 +116,7 @@
         "libutilscallstack",
         "libutils",
         "libbinder",
+        "libbinder_ndk",
         "libactivitymanager_aidl",
         "libpermission",
         "libcutils",
@@ -148,6 +150,7 @@
         "android.hardware.camera.provider@2.5",
         "android.hardware.camera.provider@2.6",
         "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V1-ndk",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
@@ -159,6 +162,7 @@
     ],
 
     static_libs: [
+        "libaidlcommonsupport",
         "libprocessinfoservice_aidl",
         "libbinderthreadstateutils",
         "media_permission-aidl-cpp",
diff --git a/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
new file mode 100644
index 0000000..db7692a
--- /dev/null
+++ b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
@@ -0,0 +1,112 @@
+/*
+ * 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 ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+
+#include "common/CameraProviderManager.h"
+
+namespace android {
+
+template <class VendorTagSectionVectorType, class VendorTagSectionType>
+status_t IdlVendorTagDescriptor::createDescriptorFromIdl(
+        const VendorTagSectionVectorType& vts,
+        sp<VendorTagDescriptor>& descriptor) {
+
+    int tagCount = 0;
+
+    for (size_t s = 0; s < vts.size(); s++) {
+        tagCount += vts[s].tags.size();
+    }
+
+    if (tagCount < 0 || tagCount > INT32_MAX) {
+        ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+        return BAD_VALUE;
+    }
+
+    Vector<uint32_t> tagArray;
+    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+    sp<IdlVendorTagDescriptor> desc = new IdlVendorTagDescriptor();
+    desc->mTagCount = tagCount;
+
+    SortedVector<String8> sections;
+    KeyedVector<uint32_t, String8> tagToSectionMap;
+
+    int idx = 0;
+    for (size_t s = 0; s < vts.size(); s++) {
+        const VendorTagSectionType& section = vts[s];
+        const char *sectionName = section.sectionName.c_str();
+        if (sectionName == NULL) {
+            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+            return BAD_VALUE;
+        }
+        String8 sectionString(sectionName);
+        sections.add(sectionString);
+
+        for (size_t j = 0; j < section.tags.size(); j++) {
+            uint32_t tag = section.tags[j].tagId;
+            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+                return BAD_VALUE;
+            }
+
+            tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+            const char *tagName = section.tags[j].tagName.c_str();
+            if (tagName == NULL) {
+                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+                return BAD_VALUE;
+            }
+            desc->mTagToNameMap.add(tag, String8(tagName));
+            tagToSectionMap.add(tag, sectionString);
+
+            int tagType = (int) section.tags[j].tagType;
+            if (tagType < 0 || tagType >= NUM_TYPES) {
+                ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+                return BAD_VALUE;
+            }
+            desc->mTagToTypeMap.add(tag, tagType);
+        }
+    }
+
+    desc->mSections = sections;
+
+    for (size_t i = 0; i < tagArray.size(); ++i) {
+        uint32_t tag = tagArray[i];
+        String8 sectionString = tagToSectionMap.valueFor(tag);
+
+        // Set up tag to section index map
+        ssize_t index = sections.indexOf(sectionString);
+        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+        // Set up reverse mapping
+        ssize_t reverseIndex = -1;
+        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+        }
+        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+    }
+
+    descriptor = std::move(desc);
+    return OK;
+}
+
+
+} // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4227d28..5cab157 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,15 +20,18 @@
 
 #include "CameraProviderManager.h"
 
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
 #include <android/hardware/camera/device/3.8/ICameraDevice.h>
 
 #include <algorithm>
 #include <chrono>
 #include "common/DepthPhotoProcessor.h"
 #include "hidl/HidlProviderInfo.h"
+#include "aidl/AidlProviderInfo.h"
 #include <dlfcn.h>
 #include <future>
 #include <inttypes.h>
+#include <android/binder_manager.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 #include <functional>
@@ -59,12 +62,43 @@
 
 const float CameraProviderManager::kDepthARTolerance = .1f;
 
+// AIDL Devices start with major version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMajorOffset = 2;
+// AIDL Devices start with minor version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMinorOffset = 7;
+
 CameraProviderManager::HidlServiceInteractionProxyImpl
 CameraProviderManager::sHidlServiceInteractionProxy{};
 
 CameraProviderManager::~CameraProviderManager() {
 }
 
+const char* FrameworkTorchStatusToString(const TorchModeStatus& s) {
+    switch (s) {
+        case TorchModeStatus::NOT_AVAILABLE:
+            return "NOT_AVAILABLE";
+        case TorchModeStatus::AVAILABLE_OFF:
+            return "AVAILABLE_OFF";
+        case TorchModeStatus::AVAILABLE_ON:
+            return "AVAILABLE_ON";
+    }
+    ALOGW("Unexpected HAL torch mode status code %d", s);
+    return "UNKNOWN_STATUS";
+}
+
+const char* FrameworkDeviceStatusToString(const CameraDeviceStatus& s) {
+    switch (s) {
+        case CameraDeviceStatus::NOT_PRESENT:
+            return "NOT_PRESENT";
+        case CameraDeviceStatus::PRESENT:
+            return "PRESENT";
+        case CameraDeviceStatus::ENUMERATING:
+            return "ENUMERATING";
+    }
+    ALOGW("Unexpected HAL device status code %d", s);
+    return "UNKNOWN_STATUS";
+}
+
 hardware::hidl_vec<hardware::hidl_string>
 CameraProviderManager::HidlServiceInteractionProxyImpl::listServices() {
     hardware::hidl_vec<hardware::hidl_string> ret;
@@ -78,17 +112,9 @@
     return ret;
 }
 
-status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
-        HidlServiceInteractionProxy* hidlProxy) {
-    std::lock_guard<std::mutex> lock(mInterfaceMutex);
-    if (hidlProxy == nullptr) {
-        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    mListener = listener;
+status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
+        HidlServiceInteractionProxy *hidlProxy) {
     mHidlServiceProxy = hidlProxy;
-    mDeviceState = 0;
-
     // Registering will trigger notifications for all already-known providers
     bool success = mHidlServiceProxy->registerForNotifications(
         /* instance name, empty means no filter */ "",
@@ -102,10 +128,54 @@
     for (const auto& instance : mHidlServiceProxy->listServices()) {
         this->addHidlProviderLocked(instance);
     }
+    return OK;
+}
+
+static std::string getFullAidlProviderName(const std::string instance) {
+    std::string aidlHalServiceDescriptor =
+            std::string(aidl::android::hardware::camera::provider::ICameraProvider::descriptor);
+   return aidlHalServiceDescriptor + "/" + instance;
+}
+
+status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
+    const char * aidlHalServiceDescriptor =
+            aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
+    auto sm = defaultServiceManager();
+    auto aidlProviders = sm->getDeclaredInstances(
+            String16(aidlHalServiceDescriptor));
+    for (const auto &aidlInstance : aidlProviders) {
+        std::string aidlServiceName =
+                getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
+        auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
+        if (res != OK) {
+            ALOGE("%s Unable to register for notifications with AIDL service manager",
+                    __FUNCTION__);
+            return res;
+        }
+        addAidlProviderLocked(aidlServiceName.c_str());
+    }
+    return OK;
+}
+
+status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
+        HidlServiceInteractionProxy* hidlProxy) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+    if (hidlProxy == nullptr) {
+        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    mListener = listener;
+    mDeviceState = 0;
+    auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
+    if (res != OK) {
+        // Logging done in called function;
+        return res;
+    }
+    res = tryToAddAidlProvidersLocked();
 
     IPCThreadState::self()->flushCommands();
 
-    return OK;
+    return res;
 }
 
 std::pair<int, int> CameraProviderManager::getCameraCount() const {
@@ -380,6 +450,22 @@
     return false;
 }
 
+template <class ProviderInfoType, class HalCameraProviderType>
+status_t CameraProviderManager::setTorchModeT(sp<ProviderInfo> &parentProvider,
+        std::shared_ptr<HalCameraProvider> *halCameraProvider) {
+    if (halCameraProvider == nullptr) {
+        return BAD_VALUE;
+    }
+    ProviderInfoType *idlProviderInfo = static_cast<ProviderInfoType *>(parentProvider.get());
+    auto idlInterface = idlProviderInfo->startProviderInterface();
+    if (idlInterface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    *halCameraProvider =
+            std::make_shared<HalCameraProviderType>(idlInterface, idlInterface->descriptor);
+    return OK;
+}
+
 status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
     std::lock_guard<std::mutex> lock(mInterfaceMutex);
 
@@ -394,18 +480,19 @@
     }
     std::shared_ptr<HalCameraProvider> halCameraProvider = nullptr;
     IPCTransport providerTransport = parentProvider->getIPCTransport();
+    status_t res = OK;
     if (providerTransport == IPCTransport::HIDL) {
-        HidlProviderInfo * hidlProviderInfo = static_cast<HidlProviderInfo *>(parentProvider.get());
-        const sp<provider::V2_4::ICameraProvider> hidlInterface =
-                hidlProviderInfo->startProviderInterface();
-        if (hidlInterface == nullptr) {
-            return DEAD_OBJECT;
+        res = setTorchModeT<HidlProviderInfo, HidlHalCameraProvider>(parentProvider,
+                &halCameraProvider);
+        if (res != OK) {
+            return res;
         }
-        halCameraProvider =
-                std::make_shared<HidlHalCameraProvider>(hidlInterface, hidlInterface->descriptor);
     } else if (providerTransport == IPCTransport::AIDL) {
-        ALOGE("%s AIDL hal providers not supported yet", __FUNCTION__);
-        return INVALID_OPERATION;
+        res = setTorchModeT<AidlProviderInfo, AidlHalCameraProvider>(parentProvider,
+                &halCameraProvider);
+        if (res != OK) {
+            return res;
+        }
     } else {
         ALOGE("%s Invalid provider transport", __FUNCTION__);
         return INVALID_OPERATION;
@@ -518,6 +605,48 @@
     return res;
 }
 
+status_t CameraProviderManager::openAidlSession(const std::string &id,
+        const std::shared_ptr<
+                aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+        /*out*/
+        std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session) {
+
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id,
+            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
+    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+    auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
+    sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
+    if (parentProvider == nullptr) {
+        return DEAD_OBJECT;
+    }
+    auto provider =
+            static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
+    if (provider == nullptr) {
+        return DEAD_OBJECT;
+    }
+    std::shared_ptr<HalCameraProvider> halCameraProvider =
+            std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
+    saveRef(DeviceMode::CAMERA, id, halCameraProvider);
+
+    auto interface = aidlDeviceInfo3->startDeviceInterface();
+    if (interface == nullptr) {
+        removeRef(DeviceMode::CAMERA, id);
+        return DEAD_OBJECT;
+    }
+
+    auto ret = interface->open(callback, session);
+    if (!ret.isOk()) {
+        removeRef(DeviceMode::CAMERA, id);
+        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+                __FUNCTION__, id.c_str(), ret.getMessage());
+        return DEAD_OBJECT;
+    }
+    return OK;
+}
+
 status_t CameraProviderManager::openHidlSession(const std::string &id,
         const sp<device::V3_2::ICameraDeviceCallback>& callback,
         /*out*/
@@ -622,6 +751,26 @@
     }
 }
 
+// We ignore sp<IBinder> param here since we need std::shared_ptr<...> which
+// will be retrieved through the ndk api through addAidlProviderLocked ->
+// tryToInitializeAidlProvider.
+void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
+    status_t res = OK;
+    std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
+    {
+        std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+        res = addAidlProviderLocked(String8(name).c_str());
+    }
+
+    sp<StatusListener> listener = getStatusListener();
+    if (nullptr != listener.get() && res == OK) {
+        listener->onNewProviderRegistered();
+    }
+
+    IPCThreadState::self()->flushCommands();
+}
+
 hardware::Return<void> CameraProviderManager::onRegistration(
         const hardware::hidl_string& /*fqName*/,
         const hardware::hidl_string& name,
@@ -653,6 +802,59 @@
     return OK;
 }
 
+void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
+        const std::vector<std::string> &devices) {
+
+    sp<StatusListener> listener = mManager->getStatusListener();
+
+    for (auto& device : devices) {
+        std::string id;
+        status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
+        if (res != OK) {
+            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
+                    __FUNCTION__, device.c_str(), strerror(-res), res);
+            continue;
+        }
+    }
+
+    ALOGI("Camera provider %s ready with %zu camera devices",
+            mProviderName.c_str(), mDevices.size());
+
+    // Process cached status callbacks
+    std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
+            std::make_unique<std::vector<CameraStatusInfoT>>();
+    {
+        std::lock_guard<std::mutex> lock(mInitLock);
+
+        for (auto& statusInfo : mCachedStatus) {
+            std::string id, physicalId;
+            status_t res = OK;
+            if (statusInfo.isPhysicalCameraStatus) {
+                res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
+                    statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
+            } else {
+                res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
+            }
+            if (res == OK) {
+                cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
+                        id.c_str(), physicalId.c_str(), statusInfo.status);
+            }
+        }
+        mCachedStatus.clear();
+
+        mInitialized = true;
+    }
+
+    // The cached status change callbacks cannot be fired directly from this
+    // function, due to same-thread deadlock trying to acquire mInterfaceMutex
+    // twice.
+    if (listener != nullptr) {
+        mInitialStatusCallbackFuture = std::async(std::launch::async,
+                &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
+                listener, std::move(cachedStatus));
+    }
+}
+
 CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
         const std::string& id,
         hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
@@ -1387,6 +1589,23 @@
     return falseRet;
 }
 
+status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
+        const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
+    using aidl::android::hardware::camera::provider::ICameraProvider;
+    std::shared_ptr<ICameraProvider> interface =
+            ICameraProvider::fromBinder(ndk::SpAIBinder(
+                    AServiceManager_getService(providerName.c_str())));
+
+    if (interface == nullptr) {
+        ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
+                providerName.c_str());
+        return BAD_VALUE;
+    }
+
+    AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
+    return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
+}
+
 status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
         const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
     sp<provider::V2_4::ICameraProvider> interface;
@@ -1395,7 +1614,7 @@
     if (interface == nullptr) {
         // The interface may not be started yet. In that case, this is not a
         // fatal error.
-        ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
+        ALOGW("%s: HIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
                 providerName.c_str());
         return BAD_VALUE;
     }
@@ -1404,6 +1623,54 @@
     return hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);
 }
 
+status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
+    // Several camera provider instances can be temporarily present.
+    // Defer initialization of a new instance until the older instance is properly removed.
+    auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
+    bool providerPresent = false;
+    bool preexisting =
+            (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
+
+    // We need to use the extracted provider name here since 'newProvider' has
+    // the fully qualified name of the provider service in case of AIDL. We want
+    // just instance name.
+    using aidl::android::hardware::camera::provider::ICameraProvider;
+    std::string extractedProviderName =
+            newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
+    for (const auto& providerInfo : mProviders) {
+        if (providerInfo->mProviderName == extractedProviderName) {
+            ALOGW("%s: Camera provider HAL with name '%s' already registered",
+                    __FUNCTION__, newProvider.c_str());
+            // Do not add new instances for lazy HAL external provider or aidl
+            // binders previously seen.
+            if (preexisting || providerInfo->isExternalLazyHAL()) {
+                return ALREADY_EXISTS;
+            } else {
+                ALOGW("%s: The new provider instance will get initialized immediately after the"
+                        " currently present instance is removed!", __FUNCTION__);
+                providerPresent = true;
+                break;
+            }
+        }
+    }
+
+    sp<AidlProviderInfo> providerInfo =
+            new AidlProviderInfo(extractedProviderName, providerInstance, this);
+
+    if (!providerPresent) {
+        status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
+        if (res != OK) {
+            return res;
+        }
+        mAidlProviderWithBinders.emplace(newProvider);
+    }
+
+    mProviders.push_back(providerInfo);
+    mProviderInstanceId++;
+
+    return OK;
+}
+
 status_t CameraProviderManager::addHidlProviderLocked(const std::string& newProvider,
         bool preexisting) {
     // Several camera provider instances can be temporarily present.
@@ -1467,9 +1734,13 @@
         for (const auto& providerInfo : mProviders) {
             if (providerInfo->mProviderName == removedProviderName) {
                 IPCTransport providerTransport = providerInfo->getIPCTransport();
+                std::string removedAidlProviderName = getFullAidlProviderName(removedProviderName);
                 switch(providerTransport) {
                     case IPCTransport::HIDL:
                         return tryToInitializeHidlProviderLocked(removedProviderName, providerInfo);
+                    case IPCTransport::AIDL:
+                        return tryToInitializeAidlProviderLocked(removedAidlProviderName,
+                                providerInfo);
                     default:
                         ALOGE("%s Unsupported Transport %d", __FUNCTION__, providerTransport);
                 }
@@ -1513,6 +1784,70 @@
     return mType;
 }
 
+status_t CameraProviderManager::ProviderInfo::addDevice(
+        const std::string& name, CameraDeviceStatus initialStatus,
+        /*out*/ std::string* parsedId) {
+
+    ALOGI("Enumerating new camera device: %s", name.c_str());
+
+    uint16_t major, minor;
+    std::string type, id;
+
+    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+    if (res != OK) {
+        return res;
+    }
+    if (getIPCTransport() == IPCTransport::AIDL) {
+        // Till HIDL support exists, map AIDL versions to HIDL.
+        // TODO:b/196432585 Explore if we can get rid of this.
+        major += kAidlDeviceMajorOffset;
+        minor += kAidlDeviceMinorOffset;
+    }
+
+    if (type != mType) {
+        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
+                type.c_str(), mType.c_str());
+        return BAD_VALUE;
+    }
+    if (mManager->isValidDeviceLocked(id, major)) {
+        ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
+                name.c_str(), id.c_str(), major);
+        return BAD_VALUE;
+    }
+
+    std::unique_ptr<DeviceInfo> deviceInfo;
+    switch (major) {
+        case 3:
+            deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
+            break;
+        default:
+            ALOGE("%s: Device %s: Unsupported IDL device HAL major version %d:", __FUNCTION__,
+                    name.c_str(), major);
+            return BAD_VALUE;
+    }
+    if (deviceInfo == nullptr) return BAD_VALUE;
+    deviceInfo->notifyDeviceStateChange(getDeviceState());
+    deviceInfo->mStatus = initialStatus;
+    bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
+
+    mDevices.push_back(std::move(deviceInfo));
+
+    mUniqueCameraIds.insert(id);
+    if (isAPI1Compatible) {
+        // addDevice can be called more than once for the same camera id if HAL
+        // supports openLegacy.
+        if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
+                id) == mUniqueAPI1CompatibleCameraIds.end()) {
+            mUniqueAPI1CompatibleCameraIds.push_back(id);
+        }
+    }
+
+    if (parsedId != nullptr) {
+        *parsedId = id;
+    }
+    return OK;
+}
+
 void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
     for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
         if ((*it)->mId == id) {
@@ -1643,6 +1978,197 @@
     return mConcurrentCameraIdCombinations;
 }
 
+void CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeInternal(
+        const std::string& cameraDeviceName, CameraDeviceStatus newStatus) {
+    sp<StatusListener> listener;
+    std::string id;
+    std::lock_guard<std::mutex> lock(mInitLock);
+    CameraDeviceStatus internalNewStatus = newStatus;
+    if (!mInitialized) {
+        mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
+                cameraDeviceName.c_str(), std::string().c_str(),
+                internalNewStatus);
+        return;
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
+            return;
+        }
+        listener = mManager->getStatusListener();
+    }
+
+    // Call without lock held to allow reentrancy into provider manager
+    if (listener != nullptr) {
+        listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
+    }
+}
+
+status_t CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeLocked(
+        std::string* id, const std::string& cameraDeviceName,
+        CameraDeviceStatus newStatus) {
+    bool known = false;
+    std::string cameraId;
+    for (auto& deviceInfo : mDevices) {
+        if (deviceInfo->mName == cameraDeviceName) {
+            Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
+            ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
+                    FrameworkDeviceStatusToString(newStatus),
+                    FrameworkDeviceStatusToString(deviceInfo->mStatus));
+            deviceInfo->mStatus = newStatus;
+            // TODO: Handle device removal (NOT_PRESENT)
+            cameraId = deviceInfo->mId;
+            known = true;
+            deviceInfo->mIsDeviceAvailable =
+                (newStatus == CameraDeviceStatus::PRESENT);
+            deviceInfo->mDeviceAvailableSignal.signal();
+            break;
+        }
+    }
+    // Previously unseen device; status must not be NOT_PRESENT
+    if (!known) {
+        if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+            ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
+                mProviderName.c_str(), cameraDeviceName.c_str());
+            return BAD_VALUE;
+        }
+        addDevice(cameraDeviceName, newStatus, &cameraId);
+    } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+        removeDevice(cameraId);
+    } else if (isExternalLazyHAL()) {
+        // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
+        // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
+        // notif. would overwrite it
+        return BAD_VALUE;
+    }
+
+    if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
+        ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
+                  __FUNCTION__, mProviderName.c_str());
+    }
+    *id = cameraId;
+    return OK;
+}
+
+void CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeInternal(
+        const std::string& cameraDeviceName,
+        const std::string& physicalCameraDeviceName,
+        CameraDeviceStatus newStatus) {
+    sp<StatusListener> listener;
+    std::string id;
+    std::string physicalId;
+    std::lock_guard<std::mutex> lock(mInitLock);
+    if (!mInitialized) {
+        mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
+                physicalCameraDeviceName, newStatus);
+        return;
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+
+        if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
+                physicalCameraDeviceName, newStatus)) {
+            return;
+        }
+
+        listener = mManager->getStatusListener();
+    }
+    // Call without lock held to allow reentrancy into provider manager
+    if (listener != nullptr) {
+        listener->onDeviceStatusChanged(String8(id.c_str()),
+                String8(physicalId.c_str()), newStatus);
+    }
+    return;
+}
+
+status_t CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeLocked(
+            std::string* id, std::string* physicalId,
+            const std::string& cameraDeviceName,
+            const std::string& physicalCameraDeviceName,
+            CameraDeviceStatus newStatus) {
+    bool known = false;
+    std::string cameraId;
+    for (auto& deviceInfo : mDevices) {
+        if (deviceInfo->mName == cameraDeviceName) {
+            cameraId = deviceInfo->mId;
+            if (!deviceInfo->mIsLogicalCamera) {
+                ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+                        __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+                return BAD_VALUE;
+            }
+            if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
+                    physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
+                ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+                        __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+                return BAD_VALUE;
+            }
+            ALOGI("Camera device %s physical device %s status is now %s",
+                    cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
+                    FrameworkDeviceStatusToString(newStatus));
+            known = true;
+            break;
+        }
+    }
+    // Previously unseen device; status must not be NOT_PRESENT
+    if (!known) {
+        ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
+                mProviderName.c_str(), cameraDeviceName.c_str(),
+                physicalCameraDeviceName.c_str());
+        return BAD_VALUE;
+    }
+
+    *id = cameraId;
+    *physicalId = physicalCameraDeviceName.c_str();
+    return OK;
+}
+
+void CameraProviderManager::ProviderInfo::torchModeStatusChangeInternal(
+        const std::string& cameraDeviceName,
+        TorchModeStatus newStatus) {
+    sp<StatusListener> listener;
+    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+    std::string id;
+    bool known = false;
+    {
+        // Hold mLock for accessing mDevices
+        std::lock_guard<std::mutex> lock(mLock);
+        for (auto& deviceInfo : mDevices) {
+            if (deviceInfo->mName == cameraDeviceName) {
+                ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
+                        FrameworkTorchStatusToString(newStatus));
+                id = deviceInfo->mId;
+                known = true;
+                systemCameraKind = deviceInfo->mSystemCameraKind;
+                if (TorchModeStatus::AVAILABLE_ON != newStatus) {
+                    mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
+                }
+                break;
+            }
+        }
+        if (!known) {
+            ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
+                    mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
+            return;
+        }
+        // no lock needed since listener is set up only once during
+        // CameraProviderManager initialization and then never changed till it is
+        // destructed.
+        listener = mManager->getStatusListener();
+     }
+    // Call without lock held to allow reentrancy into provider manager
+    // The problem with holding mLock here is that we
+    // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
+    // back into CameraProviderManager which might try to hold mLock again (eg:
+    // findDeviceInfo, which should be holding mLock while iterating through
+    // each provider's devices).
+    if (listener != nullptr) {
+        listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
+    }
+    return;
+}
+
 void CameraProviderManager::ProviderInfo::notifyDeviceInfoStateChangeLocked(
         int64_t newDeviceState) {
     std::lock_guard<std::mutex> lock(mLock);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 4568209..b67a7fa 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -33,6 +33,7 @@
 #include <utils/Errors.h>
 #include <android/hardware/ICameraService.h>
 #include <utils/IPCTransport.h>
+#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
 #include <android/hardware/camera/common/1.0/types.h>
 #include <android/hardware/camera/provider/2.5/ICameraProvider.h>
 #include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
@@ -97,6 +98,26 @@
 #define CAMERA_DEVICE_API_VERSION_3_8 HARDWARE_DEVICE_API_VERSION(3, 8)
 
 /**
+ * The vendor tag descriptor class that takes HIDL/AIDL vendor tag information as
+ * input. Not part of VendorTagDescriptor class because that class is used
+ * in AIDL generated sources which don't have access to AIDL / HIDL headers.
+ */
+class IdlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+    /**
+     * Create a VendorTagDescriptor object from the HIDL/AIDL VendorTagSection
+     * vector.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    template <class VendorTagSectionVectorType, class VendorTagSectionType>
+    static status_t createDescriptorFromIdl(
+            const VendorTagSectionVectorType& vts,
+            /*out*/
+            sp<VendorTagDescriptor>& descriptor);
+};
+
+/**
  * A manager for all camera providers available on an Android device.
  *
  * Responsible for enumerating providers and the individual camera devices
@@ -106,11 +127,13 @@
  * opening them for active use.
  *
  */
-class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
+class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification,
+        public virtual IServiceManager::LocalRegistrationCallback {
 public:
     // needs to be made friend strict since HidlProviderInfo needs to inherit
     // from CameraProviderManager::ProviderInfo which isn't a public member.
     friend struct HidlProviderInfo;
+    friend struct AidlProviderInfo;
     ~CameraProviderManager();
 
     // Tiny proxy for the static methods in a HIDL interface that communicate with the hardware
@@ -315,6 +338,13 @@
      */
     status_t notifyDeviceStateChange(int64_t newState);
 
+    status_t openAidlSession(const std::string &id,
+        const std::shared_ptr<
+                aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+        /*out*/
+        std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session);
+
+
     /**
      * Open an active session to a camera device.
      *
@@ -339,6 +369,9 @@
             const hardware::hidl_string& name,
             bool preexisting) override;
 
+    // LocalRegistrationCallback::onServiceRegistration
+    virtual void onServiceRegistration(const String16& name, const sp<IBinder> &binder) override;
+
     /**
      * Dump out information about available providers and devices
      */
@@ -402,6 +435,17 @@
         sp<hardware::camera::provider::V2_4::ICameraProvider> mCameraProvider;
     };
 
+    struct AidlHalCameraProvider : public HalCameraProvider {
+        AidlHalCameraProvider(
+                const std::shared_ptr<
+                        aidl::android::hardware::camera::provider::ICameraProvider> &provider,
+                const char *descriptor) :
+                HalCameraProvider(descriptor), mCameraProvider(provider) { };
+     private:
+        std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mCameraProvider;
+    };
+
+
     // Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
     // ICameraProvider alive while it is in use by the camera with the given ID for camera
     // capabilities
@@ -418,10 +462,11 @@
     std::mutex mProviderInterfaceMapLock;
     struct ProviderInfo : public virtual RefBase {
         friend struct HidlProviderInfo;
+        friend struct AidlProviderInfo;
         const std::string mProviderName;
         const std::string mProviderInstance;
         const metadata_vendor_id_t mProviderTagid;
-        int mMinorVersion;
+        int32_t mMinorVersion;
         sp<VendorTagDescriptor> mVendorTagDescriptor;
         bool mSetTorchModeSupported;
         bool mIsRemote;
@@ -436,6 +481,7 @@
 
         status_t dump(int fd, const Vector<String16>& args) const;
 
+        void initializeProviderInfoCommon(const std::vector<std::string> &devices);
         /**
          * Setup vendor tags for this provider
          */
@@ -452,6 +498,8 @@
 
         virtual bool successfullyStartedProviderInterface() = 0;
 
+        virtual int64_t getDeviceState() = 0;
+
         std::vector<std::unordered_set<std::string>> getConcurrentCameraIdCombinations();
 
         /**
@@ -469,7 +517,6 @@
                     const std::set<std::string>& perfClassPrimaryCameraIds,
                     int targetSdkVersion, bool *isSupported) = 0;
 
-
         /**
          * Remove all devices associated with this provider and notify listeners
          * with NOT_PRESENT state.
@@ -666,6 +713,14 @@
         // End of scope for mInitLock
 
         std::future<void> mInitialStatusCallbackFuture;
+
+        std::unique_ptr<ProviderInfo::DeviceInfo>
+        virtual initializeDeviceInfo(
+                const std::string &name, const metadata_vendor_id_t tagId,
+                const std::string &id, uint16_t minorVersion) = 0;
+
+        virtual status_t reCacheConcurrentStreamingCameraIdsLocked() = 0;
+
         void notifyInitialStatusChange(sp<StatusListener> listener,
                 std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus);
 
@@ -682,10 +737,46 @@
         // Generate vendor tag id
         static metadata_vendor_id_t generateVendorTagId(const std::string &name);
 
+        status_t addDevice(
+                const std::string& name, CameraDeviceStatus initialStatus,
+                /*out*/ std::string* parsedId);
+
+        void cameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+                CameraDeviceStatus newStatus);
+
+        status_t cameraDeviceStatusChangeLocked(
+                std::string* id, const std::string& cameraDeviceName,
+                CameraDeviceStatus newStatus);
+
+        void physicalCameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+                const std::string& physicalCameraDeviceName,
+                CameraDeviceStatus newStatus);
+
+      status_t physicalCameraDeviceStatusChangeLocked(
+            std::string* id, std::string* physicalId,
+            const std::string& cameraDeviceName,
+            const std::string& physicalCameraDeviceName,
+            CameraDeviceStatus newStatus);
+
+        void torchModeStatusChangeInternal(const std::string& cameraDeviceName,
+                TorchModeStatus newStatus);
+
         void removeDevice(std::string id);
 
     };
 
+    template <class ProviderInfoType, class HalCameraProviderType>
+    status_t setTorchModeT(sp<ProviderInfo> &parentProvider,
+            std::shared_ptr<HalCameraProvider> *halCameraProvider);
+
+    // Try to get hidl provider services declared. Expects mInterfaceMutex to be
+    // locked. Also registers for hidl provider service notifications.
+    status_t tryToInitAndAddHidlProvidersLocked(HidlServiceInteractionProxy *hidlProxy);
+
+    // Try to get aidl provider services declared. Expects mInterfaceMutex to be
+    // locked. Also registers for aidl provider service notifications.
+    status_t tryToAddAidlProvidersLocked();
+
     /**
      * Save the ICameraProvider while it is being used by a camera or torch client
      */
@@ -709,9 +800,14 @@
 
     status_t addHidlProviderLocked(const std::string& newProvider, bool preexisting = false);
 
+    status_t addAidlProviderLocked(const std::string& newProvider);
+
     status_t tryToInitializeHidlProviderLocked(const std::string& providerName,
             const sp<ProviderInfo>& providerInfo);
 
+    status_t tryToInitializeAidlProviderLocked(const std::string& providerName,
+            const sp<ProviderInfo>& providerInfo);
+
     bool isLogicalCameraLocked(const std::string& id, std::vector<std::string>* physicalCameraIds);
 
     // No method corresponding to the same provider / member belonging to the
@@ -725,6 +821,8 @@
 
     size_t mProviderInstanceId = 0;
     std::vector<sp<ProviderInfo>> mProviders;
+    // Provider names of AIDL providers with retrieved binders.
+    std::set<std::string> mAidlProviderWithBinders;
 
     static const char* deviceStatusToString(
         const hardware::camera::common::V1_0::CameraDeviceStatus&);
@@ -744,6 +842,8 @@
             std::vector<std::string>& systemCameraDeviceIds) const;
 
     status_t usbDeviceDetached(const std::string &usbDeviceId);
+    ndk::ScopedAStatus onAidlRegistration(const std::string& in_name,
+            const ::ndk::SpAIBinder& in_binder);
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/common/HalConversionsTemplated.h b/services/camera/libcameraservice/common/HalConversionsTemplated.h
new file mode 100644
index 0000000..96a715c
--- /dev/null
+++ b/services/camera/libcameraservice/common/HalConversionsTemplated.h
@@ -0,0 +1,97 @@
+/*
+ * 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 ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+#define ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+
+#include "common/CameraProviderManager.h"
+
+#include <device3/Camera3StreamInterface.h>
+
+namespace android {
+
+template <class HalCameraDeviceStatus>
+HalCameraDeviceStatus mapFrameworkToHalCameraDeviceStatus(
+        const CameraDeviceStatus& s)  {
+    switch(s) {
+        case CameraDeviceStatus::PRESENT:
+            return HalCameraDeviceStatus::PRESENT;
+        case CameraDeviceStatus::NOT_PRESENT:
+            return HalCameraDeviceStatus::NOT_PRESENT;
+        case CameraDeviceStatus::ENUMERATING:
+            return HalCameraDeviceStatus::ENUMERATING;
+    }
+    ALOGW("Unexpectedcamera device status code %d", s);
+    return HalCameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraDeviceStatus>
+CameraDeviceStatus HalToFrameworkCameraDeviceStatus(
+        const HalCameraDeviceStatus& s)  {
+    switch(s) {
+        case HalCameraDeviceStatus::PRESENT:
+            return CameraDeviceStatus::PRESENT;
+        case HalCameraDeviceStatus::NOT_PRESENT:
+            return CameraDeviceStatus::NOT_PRESENT;
+        case HalCameraDeviceStatus::ENUMERATING:
+            return CameraDeviceStatus::ENUMERATING;
+    }
+    ALOGW("Unexpectedcamera device status code %d", s);
+    return CameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraResourceCost>
+CameraResourceCost HalToFrameworkResourceCost(
+        const HalCameraResourceCost& s)  {
+    CameraResourceCost internalResourceCost;
+    internalResourceCost.resourceCost = (uint32_t)s.resourceCost;
+    for (const auto device : s.conflictingDevices) {
+        internalResourceCost.conflictingDevices.emplace_back(device.c_str());
+    }
+    return internalResourceCost;
+}
+
+template <class HalTorchModeStatus>
+TorchModeStatus HalToFrameworkTorchModeStatus(
+        const HalTorchModeStatus& s)  {
+    switch(s) {
+        case HalTorchModeStatus::NOT_AVAILABLE:
+            return TorchModeStatus::NOT_AVAILABLE;
+        case HalTorchModeStatus::AVAILABLE_OFF:
+            return TorchModeStatus::AVAILABLE_OFF;
+        case HalTorchModeStatus::AVAILABLE_ON:
+            return TorchModeStatus::AVAILABLE_ON;
+    }
+    ALOGW("Unexpectedcamera torch mode status code %d", s);
+    return TorchModeStatus::NOT_AVAILABLE;
+}
+
+template <class HalCameraDeviceStatus>
+ const char* HalDeviceStatusToString(const HalCameraDeviceStatus& s) {
+    switch(s) {
+        case HalCameraDeviceStatus::NOT_PRESENT:
+            return "NOT_PRESENT";
+        case HalCameraDeviceStatus::PRESENT:
+            return "PRESENT";
+        case HalCameraDeviceStatus::ENUMERATING:
+            return "ENUMERATING";
+    }
+    ALOGW("Unexpected HAL device status code %d", s);
+    return "UNKNOWN_STATUS";
+}
+
+}
+
+#endif
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
new file mode 100644
index 0000000..0922b74
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2021 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 "AidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
+
+#include <cutils/properties.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_manager.h>
+#include <android/hardware/ICameraService.h>
+#include <camera_metadata_hidden.h>
+
+#include "device3/ZoomRatioMapper.h"
+#include <utils/SessionConfigurationUtils.h>
+#include <utils/Trace.h>
+
+namespace {
+const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
+} // anonymous namespace
+
+namespace android {
+
+namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
+
+using namespace aidl::android::hardware;
+using namespace hardware::camera;
+using hardware::camera2::utils::CameraIdAndSessionConfiguration;
+using hardware::ICameraService;
+
+using HalDeviceStatusType = aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ICameraProvider = aidl::android::hardware::camera::provider::ICameraProvider;
+using StatusListener = CameraProviderManager::StatusListener;
+
+status_t AidlProviderInfo::mapToStatusT(const ndk::ScopedAStatus& s) {
+    using Status = aidl::android::hardware::camera::common::Status;
+    Status st = static_cast<Status>(s.getServiceSpecificError());
+    switch(st) {
+        case Status::OK:
+            return OK;
+        case Status::ILLEGAL_ARGUMENT:
+            return BAD_VALUE;
+        case Status::CAMERA_IN_USE:
+            return -EBUSY;
+        case Status::MAX_CAMERAS_IN_USE:
+            return -EUSERS;
+        case Status::METHOD_NOT_SUPPORTED:
+            return UNKNOWN_TRANSACTION;
+        case Status::OPERATION_NOT_SUPPORTED:
+            return INVALID_OPERATION;
+        case Status::CAMERA_DISCONNECTED:
+            return DEAD_OBJECT;
+        case Status::INTERNAL_ERROR:
+            return INVALID_OPERATION;
+    }
+    ALOGW("Unexpected HAL status code %d", static_cast<int>(st));
+    return INVALID_OPERATION;
+}
+
+AidlProviderInfo::AidlProviderInfo(
+            const std::string &providerName,
+            const std::string &providerInstance,
+            CameraProviderManager *manager) :
+            CameraProviderManager::ProviderInfo(providerName, providerInstance, manager) {}
+
+status_t AidlProviderInfo::initializeAidlProvider(
+        std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
+
+    status_t res = parseProviderName(mProviderName, &mType, &mId);
+    if (res != OK) {
+        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
+            mProviderName.c_str(), interface->isRemote());
+
+    // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
+    // before setCallback returns
+    mCallbacks =
+            ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
+    ndk::ScopedAStatus status =
+            interface->setCallback(mCallbacks);
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
+                __FUNCTION__, mProviderName.c_str(), status.getMessage());
+        return mapToStatusT(status);
+    }
+
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
+    auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
+    if (link != STATUS_OK) {
+        ALOGW("%s: Unable to link to provider '%s' death notifications",
+                __FUNCTION__, mProviderName.c_str());
+        return DEAD_OBJECT;
+    }
+
+    if (!kEnableLazyHal) {
+        // Save HAL reference indefinitely
+        mSavedInterface = interface;
+    } else {
+        mActiveInterface = interface;
+    }
+
+    ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
+            __FUNCTION__, mProviderName.c_str(), mDeviceState);
+    notifyDeviceStateChange(currentDeviceState);
+
+    res = setUpVendorTags();
+    if (res != OK) {
+        ALOGE("%s: Unable to set up vendor tags from provider '%s'",
+                __FUNCTION__, mProviderName.c_str());
+        return res;
+     }
+
+    // Get initial list of camera devices, if any
+    std::vector<std::string> devices;
+    std::vector<std::string> retDevices;
+    status = interface->getCameraIdList(&retDevices);
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
+                __FUNCTION__, mProviderName.c_str(), status.getMessage());
+        return mapToStatusT(status);
+    }
+
+    for (auto& name : retDevices) {
+        uint16_t major, minor;
+        std::string type, id;
+        status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+        if (res != OK) {
+            ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
+            return res;
+        } else {
+            devices.push_back(name);
+            mProviderPublicCameraIds.push_back(id);
+        }
+    }
+
+    // Get list of concurrent streaming camera device combinations
+    res = getConcurrentCameraIdsInternalLocked(interface);
+    if (res != OK) {
+        return res;
+    }
+
+    mSetTorchModeSupported = true;
+
+    mIsRemote = interface->isRemote();
+
+    initializeProviderInfoCommon(devices);
+    return OK;
+}
+
+void AidlProviderInfo::binderDied(void *cookie) {
+    AidlProviderInfo *provider = reinterpret_cast<AidlProviderInfo *>(cookie);
+    ALOGI("Camera provider '%s' has died; removing it", provider->mProviderInstance.c_str());
+    provider->mManager->removeProvider(provider->mProviderInstance);
+}
+
+status_t AidlProviderInfo::setUpVendorTags() {
+    if (mVendorTagDescriptor != nullptr)
+        return OK;
+
+    std::vector<camera::common::VendorTagSection> vts;
+    ::ndk::ScopedAStatus status;
+    const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    status = interface->getVendorTags(&vts);
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
+                __FUNCTION__, mProviderName.c_str(), status.getMessage());
+        return mapToStatusT(status);
+    }
+
+    // Read all vendor tag definitions into a descriptor
+    status_t res;
+    if ((res =
+            IdlVendorTagDescriptor::
+                    createDescriptorFromIdl<std::vector<camera::common::VendorTagSection>,
+                            camera::common::VendorTagSection>(vts, /*out*/mVendorTagDescriptor))
+            != OK) {
+        ALOGE("%s: Could not generate descriptor from vendor tag operations,"
+                "received error %s (%d). Camera clients will not be able to use"
+                "vendor tags", __FUNCTION__, strerror(res), res);
+        return res;
+    }
+
+    return OK;
+}
+
+status_t AidlProviderInfo::notifyDeviceStateChange(int64_t newDeviceState) {
+
+    mDeviceState = newDeviceState;
+    // Check if the provider is currently active - not going to start it up for this notification
+    auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+    if (interface != nullptr) {
+        // Send current device state
+        interface->notifyDeviceStateChange(mDeviceState);
+    }
+    return OK;
+}
+
+bool AidlProviderInfo::successfullyStartedProviderInterface() {
+    return startProviderInterface() != nullptr;
+}
+
+std::shared_ptr<camera::device::ICameraDevice>
+AidlProviderInfo::startDeviceInterface(const std::string &name) {
+    ::ndk::ScopedAStatus status;
+    std::shared_ptr<camera::device::ICameraDevice> cameraInterface;
+    const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+    if (interface == nullptr) {
+        return nullptr;
+    }
+    status = interface->getCameraDeviceInterface(name, &cameraInterface);
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
+                __FUNCTION__, name.c_str(), status.getMessage());
+        return nullptr;
+    }
+    return cameraInterface;
+}
+
+const std::shared_ptr<ICameraProvider> AidlProviderInfo::startProviderInterface() {
+    ATRACE_CALL();
+    ALOGV("Request to start camera provider: %s", mProviderName.c_str());
+    if (mSavedInterface != nullptr) {
+        return mSavedInterface;
+    }
+    if (!kEnableLazyHal) {
+        ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
+        return nullptr;
+    }
+
+    auto interface = mActiveInterface.lock();
+    if (interface == nullptr) {
+        // Try to get service without starting
+        interface =
+                    ICameraProvider::fromBinder(
+                            ndk::SpAIBinder(AServiceManager_checkService(mProviderName.c_str())));
+        if (interface == nullptr) {
+            ALOGV("Camera provider actually needs restart, calling getService(%s)",
+                  mProviderName.c_str());
+            interface =
+                            ICameraProvider::fromBinder(
+                                    ndk::SpAIBinder(
+                                                AServiceManager_getService(mProviderName.c_str())));
+
+            // Set all devices as ENUMERATING, provider should update status
+            // to PRESENT after initializing.
+            // This avoids failing getCameraDeviceInterface_V3_x before devices
+            // are ready.
+            for (auto& device : mDevices) {
+              device->mIsDeviceAvailable = false;
+            }
+
+            interface->setCallback(mCallbacks);
+            auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(),
+                    this);
+            if (link != STATUS_OK) {
+                ALOGW("%s: Unable to link to provider '%s' death notifications",
+                        __FUNCTION__, mProviderName.c_str());
+                mManager->removeProvider(mProviderName);
+                return nullptr;
+            }
+
+            // Send current device state
+            interface->notifyDeviceStateChange(mDeviceState);
+        }
+        mActiveInterface = interface;
+    } else {
+        ALOGV("Camera provider (%s) already in use. Re-using instance.",
+              mProviderName.c_str());
+    }
+
+    return interface;
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::cameraDeviceStatusChange(
+    const std::string& cameraDeviceName,
+    HalDeviceStatusType newStatus) {
+    sp<AidlProviderInfo> parent = mParent.promote();
+    if (parent == nullptr) {
+        ALOGE("%s: Parent provider not alive", __FUNCTION__);
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return parent->cameraDeviceStatusChange(cameraDeviceName, newStatus);
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::torchModeStatusChange(
+            const std::string& cameraDeviceName,
+            aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+    sp<AidlProviderInfo> parent = mParent.promote();
+    if (parent == nullptr) {
+        ALOGE("%s: Parent provider not alive", __FUNCTION__);
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return parent->torchModeStatusChange(cameraDeviceName, newStatus);
+
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::physicalCameraDeviceStatusChange(
+            const std::string& cameraDeviceName,
+            const std::string& physicalCameraDeviceName,
+            HalDeviceStatusType newStatus) {
+    sp<AidlProviderInfo> parent = mParent.promote();
+    if (parent == nullptr) {
+        ALOGE("%s: Parent provider not alive", __FUNCTION__);
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return parent->physicalCameraDeviceStatusChange(cameraDeviceName, physicalCameraDeviceName,
+            newStatus);
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::cameraDeviceStatusChange(const std::string& cameraDeviceName,
+            HalDeviceStatusType newStatus) {
+    cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::torchModeStatusChange(const std::string& cameraDeviceName,
+            aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+    torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
+    return ::ndk::ScopedAStatus::ok();
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::physicalCameraDeviceStatusChange(
+            const std::string& cameraDeviceName,
+            const std::string& physicalCameraDeviceName,
+            HalDeviceStatusType newStatus) {
+    physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+            HalToFrameworkCameraDeviceStatus(newStatus));
+    return ::ndk::ScopedAStatus::ok();
+};
+
+std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
+    AidlProviderInfo::initializeDeviceInfo(
+        const std::string &name, const metadata_vendor_id_t tagId,
+        const std::string &id, uint16_t minorVersion) {
+    ::ndk::ScopedAStatus status;
+
+    auto cameraInterface = startDeviceInterface(name);
+    if (cameraInterface == nullptr) return nullptr;
+
+    camera::common::CameraResourceCost resourceCost;
+    status = cameraInterface->getResourceCost(&resourceCost);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
+                name.c_str(), status.getMessage());
+        return nullptr;
+    }
+
+    for (auto& conflictName : resourceCost.conflictingDevices) {
+        uint16_t major, minor;
+        std::string type, id;
+        status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
+        if (res != OK) {
+            ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
+            return nullptr;
+        }
+        conflictName = id;
+    }
+
+    return std::unique_ptr<DeviceInfo3>(
+        new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
+                this, mProviderPublicCameraIds, cameraInterface));
+}
+
+status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
+
+    // Check if the provider is currently active - not going to start it up for this notification
+    auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+    if (interface == nullptr) {
+        ALOGE("%s: camera provider interface for %s is not valid", __FUNCTION__,
+                mProviderName.c_str());
+        return INVALID_OPERATION;
+    }
+
+    return getConcurrentCameraIdsInternalLocked(interface);
+}
+
+status_t AidlProviderInfo::getConcurrentCameraIdsInternalLocked(
+        std::shared_ptr<ICameraProvider> &interface) {
+    if (interface == nullptr) {
+        ALOGE("%s: null interface provided", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    std::vector<aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination> combs;
+    ::ndk::ScopedAStatus status = interface->getConcurrentCameraIds(&combs);
+
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error in getting concurrent camera ID list from provider '%s'",
+                __FUNCTION__, mProviderName.c_str());
+        return mapToStatusT(status);
+    }
+    mConcurrentCameraIdCombinations.clear();
+    for (const auto& combination : combs) {
+        std::unordered_set<std::string> deviceIds;
+        for (const auto &cameraDeviceId : combination.combination) {
+            deviceIds.insert(cameraDeviceId.c_str());
+        }
+        mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
+    }
+
+    return OK;
+}
+
+AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
+        const std::string& name,
+        const metadata_vendor_id_t tagId,
+        const std::string &id, uint16_t minorVersion,
+        const CameraResourceCost& resourceCost,
+        sp<CameraProviderManager::ProviderInfo> parentProvider,
+        const std::vector<std::string>& publicCameraIds,
+        std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface) :
+        DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
+
+    // Get camera characteristics and initialize flash unit availability
+    aidl::android::hardware::camera::device::CameraMetadata chars;
+    ::ndk::ScopedAStatus status = interface->getCameraCharacteristics(&chars);
+    std::vector<uint8_t> &metadata = chars.metadata;
+    camera_metadata_t *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
+    size_t expectedSize = metadata.size();
+    int resV = validate_camera_metadata_structure(buffer, &expectedSize);
+    if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
+        set_camera_metadata_vendor_id(buffer, mProviderTagid);
+        mCameraCharacteristics = buffer;
+    } else {
+        ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+        return;
+    }
+
+    if (!status.isOk()) {
+        ALOGE("%s: Transaction error getting camera characteristics for device %s"
+                " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
+                status.getMessage());
+        return;
+    }
+
+    if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+        const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
+        if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
+            for (size_t i = 0; i < stateMap.count; i += 2) {
+                mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
+            }
+        } else {
+            ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
+                    stateMap.count);
+        }
+    }
+
+    mSystemCameraKind = getSystemCameraKind();
+
+    status_t res = fixupMonochromeTags();
+    if (OK != res) {
+        ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return;
+    }
+    auto stat = addDynamicDepthTags();
+    if (OK != stat) {
+        ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+                stat);
+    }
+    res = deriveHeicTags();
+    if (OK != res) {
+        ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+    }
+
+    if (camera3::SessionConfigurationUtils::isUltraHighResolutionSensor(mCameraCharacteristics)) {
+        status_t status = addDynamicDepthTags(/*maxResolution*/true);
+        if (OK != status) {
+            ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
+                    __FUNCTION__, strerror(-status), status);
+        }
+
+        status = deriveHeicTags(/*maxResolution*/true);
+        if (OK != status) {
+            ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
+                    "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
+        }
+    }
+
+    res = addRotateCropTags();
+    if (OK != res) {
+        ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+    }
+    res = addPreCorrectionActiveArraySize();
+    if (OK != res) {
+        ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
+                strerror(-res), res);
+    }
+    res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+            &mCameraCharacteristics, &mSupportNativeZoomRatio);
+    if (OK != res) {
+        ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+    }
+
+    camera_metadata_entry flashAvailable =
+            mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
+    if (flashAvailable.count == 1 &&
+            flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+        mHasFlashUnit = true;
+    } else {
+        mHasFlashUnit = false;
+    }
+
+    camera_metadata_entry entry =
+            mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
+    if (entry.count == 1) {
+        mTorchDefaultStrengthLevel = entry.data.i32[0];
+    } else {
+        mTorchDefaultStrengthLevel = 0;
+    }
+    entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
+    if (entry.count == 1) {
+        mTorchMaximumStrengthLevel = entry.data.i32[0];
+    } else {
+        mTorchMaximumStrengthLevel = 0;
+    }
+
+    mTorchStrengthLevel = 0;
+
+    queryPhysicalCameraIds();
+
+    // Get physical camera characteristics if applicable
+    if (mIsLogicalCamera) {
+        for (auto& id : mPhysicalIds) {
+            if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
+                    mPublicCameraIds.end()) {
+                continue;
+            }
+
+            aidl::android::hardware::camera::device::CameraMetadata pChars;
+            status = interface->getPhysicalCameraCharacteristics(id, &pChars);
+            if (!status.isOk()) {
+                ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
+                        __FUNCTION__, id.c_str(), id.c_str(), status.getMessage());
+                return;
+            }
+            std::vector<uint8_t> &pMetadata = pChars.metadata;
+            camera_metadata_t *pBuffer =
+                    reinterpret_cast<camera_metadata_t*>(pMetadata.data());
+            size_t expectedSize = pMetadata.size();
+            int res = validate_camera_metadata_structure(pBuffer, &expectedSize);
+            if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+                set_camera_metadata_vendor_id(pBuffer, mProviderTagid);
+                mPhysicalCameraCharacteristics[id] = pBuffer;
+            } else {
+                ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+                return;
+            }
+
+            res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+                    &mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
+            if (OK != res) {
+                ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+                        __FUNCTION__, strerror(-res), res);
+            }
+        }
+    }
+
+    if (!kEnableLazyHal) {
+        // Save HAL reference indefinitely
+        mSavedInterface = interface;
+    }
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::setTorchMode(bool enabled) {
+    const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+    ::ndk::ScopedAStatus s = interface->setTorchMode(enabled);
+    if (!s.isOk()) {
+        ALOGE("%s Unable to set torch mode: %s", __FUNCTION__, s.getMessage());
+        return mapToStatusT(s);
+    }
+    return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::turnOnTorchWithStrengthLevel(
+        int32_t torchStrength) {
+    const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+
+    ::ndk::ScopedAStatus s = interface->turnOnTorchWithStrengthLevel(torchStrength);
+    if (!s.isOk()) {
+        ALOGE("%s Unable to set torch mode strength %d : %s", __FUNCTION__, torchStrength,
+                s.getMessage());
+        return mapToStatusT(s);
+    }
+    mTorchStrengthLevel = torchStrength;
+    return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
+    if (torchStrength == nullptr) {
+        return BAD_VALUE;
+    }
+    const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+
+    ::ndk::ScopedAStatus status = interface->getTorchStrengthLevel(torchStrength);
+    if (!status.isOk()) {
+        ALOGE("%s: Couldn't get torch strength level: %s", __FUNCTION__, status.getMessage());
+        return mapToStatusT(status);
+    }
+    return OK;
+}
+
+std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+AidlProviderInfo::AidlDeviceInfo3::startDeviceInterface() {
+    Mutex::Autolock l(mDeviceAvailableLock);
+    std::shared_ptr<camera::device::ICameraDevice> device;
+    ATRACE_CALL();
+    if (mSavedInterface == nullptr) {
+        sp<AidlProviderInfo> parentProvider =
+                static_cast<AidlProviderInfo *>(mParentProvider.promote().get());
+        if (parentProvider != nullptr) {
+            // Wait for lazy HALs to confirm device availability
+            if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
+                ALOGV("%s: Wait for external device to become available %s",
+                      __FUNCTION__,
+                      mId.c_str());
+
+                auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
+                                                         kDeviceAvailableTimeout);
+                if (res != OK) {
+                    ALOGE("%s: Failed waiting for device to become available",
+                          __FUNCTION__);
+                    return nullptr;
+                }
+            }
+
+            device = parentProvider->startDeviceInterface(mName);
+        }
+    } else {
+        device = mSavedInterface;
+    }
+    return device;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::dumpState(int fd) {
+    native_handle_t* handle = native_handle_create(1,0);
+    handle->data[0] = fd;
+    const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+    ::ndk::ScopedFileDescriptor sFd;
+    sFd.set(fcntl(fd, F_DUPFD_CLOEXEC, 0));
+    auto ret = interface->dumpState(sFd);
+    native_handle_delete(handle);
+    if (!ret.isOk()) {
+        return mapToStatusT(ret);
+    }
+    return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
+        const SessionConfiguration &configuration, bool overrideForPerfClass, bool *status) {
+
+    camera::device::StreamConfiguration streamConfiguration;
+    bool earlyExit = false;
+    camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+          CameraMetadata physicalChars;
+          getPhysicalCameraCharacteristics(id.c_str(), &physicalChars);
+          return physicalChars;
+    };
+    auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
+            String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
+            streamConfiguration, overrideForPerfClass, &earlyExit);
+
+    if (!bRes.isOk()) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (earlyExit) {
+        *status = false;
+        return OK;
+    }
+
+    const std::shared_ptr<camera::device::ICameraDevice> interface =
+            startDeviceInterface();
+
+    if (interface == nullptr) {
+        return DEAD_OBJECT;
+    }
+
+    ::ndk::ScopedAStatus ret =
+        interface->isStreamCombinationSupported(streamConfiguration, status);
+    if (!ret.isOk()) {
+        *status = false;
+        ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
+        return mapToStatusT(ret);
+    }
+    return OK;
+
+}
+
+status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
+        const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+        const std::set<std::string>& perfClassPrimaryCameraIds,
+        int targetSdkVersion,
+        std::vector<camera::provider::CameraIdAndStreamCombination>
+                *halCameraIdsAndStreamCombinations,
+        bool *earlyExit) {
+    binder::Status bStatus = binder::Status::ok();
+    std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamsV;
+    bool shouldExit = false;
+    status_t res = OK;
+    for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
+        const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
+        camera::device::StreamConfiguration streamConfiguration;
+        CameraMetadata deviceInfo;
+        bool overrideForPerfClass =
+                SessionConfigurationUtils::targetPerfClassPrimaryCamera(
+                        perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
+        res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo);
+        if (res != OK) {
+            return res;
+        }
+        camera3::metadataGetter getMetadata =
+                [this](const String8 &id, bool overrideForPerfClass) {
+                    CameraMetadata physicalDeviceInfo;
+                    mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+                                                   &physicalDeviceInfo);
+                    return physicalDeviceInfo;
+                };
+        std::vector<std::string> physicalCameraIds;
+        mManager->isLogicalCameraLocked(cameraId, &physicalCameraIds);
+        bStatus =
+            SessionConfigurationUtils::convertToHALStreamCombination(
+                    cameraIdAndSessionConfig.mSessionConfiguration,
+                    String8(cameraId.c_str()), deviceInfo, getMetadata,
+                    physicalCameraIds, streamConfiguration,
+                    overrideForPerfClass, &shouldExit);
+        if (!bStatus.isOk()) {
+            ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+        if (shouldExit) {
+            *earlyExit = true;
+            return OK;
+        }
+        camera::provider::CameraIdAndStreamCombination halCameraIdAndStream;
+        halCameraIdAndStream.cameraId = cameraId;
+        halCameraIdAndStream.streamConfiguration = streamConfiguration;
+        halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
+    }
+    *halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
+    return OK;
+}
+
+status_t AidlProviderInfo::isConcurrentSessionConfigurationSupported(
+        const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+        const std::set<std::string>& perfClassPrimaryCameraIds,
+        int targetSdkVersion, bool *isSupported) {
+
+      std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamCombinations;
+      bool knowUnsupported = false;
+      status_t res = convertToAidlHALStreamCombinationAndCameraIdsLocked(
+              cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds,
+              targetSdkVersion, &halCameraIdsAndStreamCombinations, &knowUnsupported);
+      if (res != OK) {
+          ALOGE("%s unable to convert session configurations provided to HAL stream"
+                "combinations", __FUNCTION__);
+          return res;
+      }
+      if (knowUnsupported) {
+          // We got to know the streams aren't valid before doing the HAL
+          // call itself.
+          *isSupported = false;
+          return OK;
+      }
+
+      // Check if the provider is currently active - not going to start it up for this notification
+      auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+      if (interface == nullptr) {
+          // TODO: This might be some other problem
+          return INVALID_OPERATION;
+      }
+      ::ndk::ScopedAStatus status = interface->isConcurrentStreamCombinationSupported(
+              halCameraIdsAndStreamCombinations, isSupported);
+      if (!status.isOk()) {
+          *isSupported = false;
+          ALOGE("%s: hal interface session configuration query failed", __FUNCTION__);
+          return mapToStatusT(status);
+      }
+
+    return OK;
+}
+
+} //namespace android
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
new file mode 100644
index 0000000..aa71e85
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+
+#include "common/CameraProviderManager.h"
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/provider/BnCameraProviderCallback.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+
+namespace android {
+
+struct AidlProviderInfo : public CameraProviderManager::ProviderInfo {
+    // Current overall Android device physical status
+    int64_t mDeviceState;
+
+    // This pointer is used to keep a reference to the ICameraProvider that was last accessed.
+    std::weak_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mActiveInterface;
+
+    std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mSavedInterface;
+
+    AidlProviderInfo(
+            const std::string &providerName,
+            const std::string &providerInstance,
+            CameraProviderManager *manager);
+
+    static status_t mapToStatusT(const ndk::ScopedAStatus& s);
+
+    // Start camera device interface, start the camera provider process for lazy
+    // hals, if needed
+    status_t initializeAidlProvider(
+        std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>& interface,
+        int64_t currentDeviceState);
+
+    static void binderDied(void *cookie);
+
+    virtual IPCTransport getIPCTransport() override {return IPCTransport::AIDL;}
+
+    const std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
+    startProviderInterface();
+
+    virtual status_t setUpVendorTags() override;
+    virtual status_t notifyDeviceStateChange(int64_t newDeviceState) override;
+
+    virtual bool successfullyStartedProviderInterface() override;
+
+    virtual int64_t getDeviceState() override { return mDeviceState; };
+
+    /**
+     * Query the camera provider for concurrent stream configuration support
+     */
+    virtual status_t isConcurrentSessionConfigurationSupported(
+        const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+        const std::set<std::string>& perfClassPrimaryCameraIds,
+        int targetSdkVersion, bool *isSupported) override;
+
+    std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+            startDeviceInterface(const std::string &deviceName);
+
+    // AIDL ICameraProviderCallback interface - these lock the parent
+    // mInterfaceMutex
+
+    ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+            ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+    ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+            ::aidl::android::hardware::camera::common::TorchModeStatus newStatus);
+
+    ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+            const std::string& cameraDeviceName,
+            const std::string& physicalCameraDeviceName,
+            ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+    struct AidlProviderCallbacks :
+            public aidl::android::hardware::camera::provider::BnCameraProviderCallback {
+        AidlProviderCallbacks(wp<AidlProviderInfo> parent) : mParent(parent) { }
+        virtual ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+                ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+        virtual ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+                ::aidl::android::hardware::camera::common::TorchModeStatus newStatus) override;
+
+        virtual ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+                const std::string& cameraDeviceName,
+                const std::string& physicalCameraDeviceName,
+                ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+       private:
+        wp<AidlProviderInfo> mParent = nullptr;
+
+    };
+
+    struct AidlDeviceInfo3 : public CameraProviderManager::ProviderInfo::DeviceInfo3 {
+
+        //TODO: fix init
+        const hardware::hidl_version mVersion = hardware::hidl_version{3, 2};
+        std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+                mSavedInterface = nullptr;
+
+        AidlDeviceInfo3(const std::string& , const metadata_vendor_id_t ,
+                const std::string &, uint16_t ,
+                const CameraResourceCost& ,
+                sp<ProviderInfo> ,
+                const std::vector<std::string>& ,
+                std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>);
+
+        ~AidlDeviceInfo3() {}
+
+        virtual status_t setTorchMode(bool enabled) override;
+        virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) override;
+        virtual status_t getTorchStrengthLevel(int32_t *torchStrength) override;
+
+        virtual status_t dumpState(int fd) override;
+
+        virtual status_t isSessionConfigurationSupported(
+                const SessionConfiguration &/*configuration*/,
+                bool overrideForPerfClass,
+                bool *status/*status*/);
+
+        std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+                startDeviceInterface();
+    };
+
+ private:
+
+    // Helper for initializeDeviceInfo to use the right CameraProvider get method.
+    virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+            const metadata_vendor_id_t , const std::string &,
+            uint16_t ) override;
+
+    virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
+
+    //Expects to have mLock locked
+
+    status_t getConcurrentCameraIdsInternalLocked(
+        std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> &interface);
+
+    //expects to have mManager->mInterfaceMutex locked
+
+    status_t convertToAidlHALStreamCombinationAndCameraIdsLocked(
+        const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+        const std::set<std::string>& perfClassPrimaryCameraIds,
+        int targetSdkVersion,
+        std::vector<aidl::android::hardware::camera::provider::CameraIdAndStreamCombination>
+                *halCameraIdsAndStreamCombinations,
+        bool *earlyExit);
+    std::shared_ptr<AidlProviderCallbacks> mCallbacks = nullptr;
+    ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+};
+
+} // namespace android
+#endif
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index e8432a6..3c5ea75 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 #include "HidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
 
 #include <cutils/properties.h>
 
@@ -42,6 +44,7 @@
 
 
 using StatusListener = CameraProviderManager::StatusListener;
+using HalDeviceStatusType = android::hardware::camera::common::V1_0::CameraDeviceStatus;
 
 using hardware::camera::provider::V2_5::DeviceState;
 using hardware::ICameraService;
@@ -111,83 +114,6 @@
     return "UNKNOWN_ERROR";
 }
 
-static common::V1_0::CameraDeviceStatus mapToHidlCameraDeviceStatus(const CameraDeviceStatus& s)  {
-    switch(s) {
-        case CameraDeviceStatus::PRESENT:
-            return common::V1_0::CameraDeviceStatus::PRESENT;
-        case CameraDeviceStatus::NOT_PRESENT:
-            return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
-        case CameraDeviceStatus::ENUMERATING:
-            return common::V1_0::CameraDeviceStatus::ENUMERATING;
-    }
-    ALOGW("Unexpectedcamera device status code %d", s);
-    return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
-}
-
-static CameraDeviceStatus hidlToInternalCameraDeviceStatus(
-        const common::V1_0::CameraDeviceStatus& s)  {
-    switch(s) {
-        case common::V1_0::CameraDeviceStatus::PRESENT:
-            return CameraDeviceStatus::PRESENT;
-        case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
-            return CameraDeviceStatus::NOT_PRESENT;
-        case common::V1_0::CameraDeviceStatus::ENUMERATING:
-            return CameraDeviceStatus::ENUMERATING;
-    }
-    ALOGW("Unexpectedcamera device status code %d", s);
-    return CameraDeviceStatus::NOT_PRESENT;
-}
-
-static TorchModeStatus hidlToInternalTorchModeStatus(
-        const common::V1_0::TorchModeStatus& s)  {
-    switch(s) {
-        case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
-            return TorchModeStatus::NOT_AVAILABLE;
-        case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
-            return TorchModeStatus::AVAILABLE_OFF;
-        case common::V1_0::TorchModeStatus::AVAILABLE_ON:
-            return TorchModeStatus::AVAILABLE_ON;
-    }
-    ALOGW("Unexpectedcamera torch mode status code %d", s);
-    return TorchModeStatus::NOT_AVAILABLE;
-}
-
-static CameraResourceCost hidlToInternalResourceCost(
-        const common::V1_0::CameraResourceCost& s)  {
-    CameraResourceCost internalResourceCost;
-    internalResourceCost.resourceCost = s.resourceCost;
-    for (const auto device : s.conflictingDevices) {
-        internalResourceCost.conflictingDevices.emplace_back(device.c_str());
-    }
-    return internalResourceCost;
-}
-
-static const char* deviceStatusToString(const common::V1_0::CameraDeviceStatus& s) {
-    switch(s) {
-        case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
-            return "NOT_PRESENT";
-        case common::V1_0::CameraDeviceStatus::PRESENT:
-            return "PRESENT";
-        case common::V1_0::CameraDeviceStatus::ENUMERATING:
-            return "ENUMERATING";
-    }
-    ALOGW("Unexpected HAL device status code %d", s);
-    return "UNKNOWN_STATUS";
-}
-
-static const char* torchStatusToString(const common::V1_0::TorchModeStatus& s) {
-    switch(s) {
-        case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
-            return "NOT_AVAILABLE";
-        case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
-            return "AVAILABLE_OFF";
-        case common::V1_0::TorchModeStatus::AVAILABLE_ON:
-            return "AVAILABLE_ON";
-    }
-    ALOGW("Unexpected HAL torch mode status code %d", s);
-    return "UNKNOWN_STATUS";
-}
-
 status_t HidlProviderInfo::initializeHidlProvider(
         sp<provider::V2_4::ICameraProvider>& interface,
         int64_t currentDeviceState) {
@@ -326,55 +252,7 @@
 
     mIsRemote = interface->isRemote();
 
-    sp<StatusListener> listener = mManager->getStatusListener();
-    for (auto& device : devices) {
-        std::string id;
-        status_t res = addDevice(device, common::V1_0::CameraDeviceStatus::PRESENT, &id);
-        if (res != OK) {
-            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
-                    __FUNCTION__, device.c_str(), strerror(-res), res);
-            continue;
-        }
-    }
-
-    ALOGI("Camera provider %s ready with %zu camera devices",
-            mProviderName.c_str(), mDevices.size());
-
-    // Process cached status callbacks
-    std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
-            std::make_unique<std::vector<CameraStatusInfoT>>();
-    {
-        std::lock_guard<std::mutex> lock(mInitLock);
-
-        for (auto& statusInfo : mCachedStatus) {
-            std::string id, physicalId;
-            status_t res = OK;
-            if (statusInfo.isPhysicalCameraStatus) {
-                res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
-                    statusInfo.cameraId, statusInfo.physicalCameraId,
-                    mapToHidlCameraDeviceStatus(statusInfo.status));
-            } else {
-                res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId,
-                        mapToHidlCameraDeviceStatus(statusInfo.status));
-            }
-            if (res == OK) {
-                cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
-                        id.c_str(), physicalId.c_str(), statusInfo.status);
-            }
-        }
-        mCachedStatus.clear();
-
-        mInitialized = true;
-    }
-
-    // The cached status change callbacks cannot be fired directly from this
-    // function, due to same-thread deadlock trying to acquire mInterfaceMutex
-    // twice.
-    if (listener != nullptr) {
-        mInitialStatusCallbackFuture = std::async(std::launch::async,
-                &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
-                listener, std::move(cachedStatus));
-    }
+    initializeProviderInfoCommon(devices);
 
     return OK;
 }
@@ -409,7 +287,10 @@
 
     // Read all vendor tag definitions into a descriptor
     status_t res;
-    if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/mVendorTagDescriptor))
+    if ((res = IdlVendorTagDescriptor::createDescriptorFromIdl<
+                hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>,
+                        hardware::camera::common::V1_0::VendorTagSection>(vts,
+                                /*out*/mVendorTagDescriptor))
             != OK) {
         ALOGE("%s: Could not generate descriptor from vendor tag operations,"
                 "received error %s (%d). Camera clients will not be able to use"
@@ -539,256 +420,25 @@
 
 hardware::Return<void> HidlProviderInfo::cameraDeviceStatusChange(
         const hardware::hidl_string& cameraDeviceName,
-        hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
-    sp<StatusListener> listener;
-    std::string id;
-    std::lock_guard<std::mutex> lock(mInitLock);
-    CameraDeviceStatus internalNewStatus = hidlToInternalCameraDeviceStatus(newStatus);
-    if (!mInitialized) {
-        mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
-                cameraDeviceName.c_str(), std::string().c_str(),
-                internalNewStatus);
-        return hardware::Void();
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(mLock);
-        if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
-            return hardware::Void();
-        }
-        listener = mManager->getStatusListener();
-    }
-
-    // Call without lock held to allow reentrancy into provider manager
-    if (listener != nullptr) {
-        listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
-    }
-
+        HalDeviceStatusType newStatus) {
+    cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
     return hardware::Void();
 }
 
-status_t HidlProviderInfo::addDevice(const std::string& name,
-        common::V1_0::CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
-
-    ALOGI("Enumerating new camera device: %s", name.c_str());
-
-    uint16_t major, minor;
-    std::string type, id;
-
-    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
-    if (res != OK) {
-        return res;
-    }
-    if (type != mType) {
-        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
-                type.c_str(), mType.c_str());
-        return BAD_VALUE;
-    }
-    if (mManager->isValidDeviceLocked(id, major)) {
-        ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
-                name.c_str(), id.c_str(), major);
-        return BAD_VALUE;
-    }
-
-    std::unique_ptr<DeviceInfo> deviceInfo;
-    switch (major) {
-        case 1:
-            ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:", __FUNCTION__,
-                    name.c_str(), major);
-            return BAD_VALUE;
-        case 3:
-            deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
-            break;
-        default:
-            ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
-                    name.c_str(), major);
-            return BAD_VALUE;
-    }
-    if (deviceInfo == nullptr) return BAD_VALUE;
-    deviceInfo->notifyDeviceStateChange(mDeviceState);
-    deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(initialStatus);
-    bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
-
-    mDevices.push_back(std::move(deviceInfo));
-
-    mUniqueCameraIds.insert(id);
-    if (isAPI1Compatible) {
-        // addDevice can be called more than once for the same camera id if HAL
-        // supports openLegacy.
-        if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
-                id) == mUniqueAPI1CompatibleCameraIds.end()) {
-            mUniqueAPI1CompatibleCameraIds.push_back(id);
-        }
-    }
-
-    if (parsedId != nullptr) {
-        *parsedId = id;
-    }
-    return OK;
-}
-
-status_t HidlProviderInfo::cameraDeviceStatusChangeLocked(
-        std::string* id, const hardware::hidl_string& cameraDeviceName,
-        hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
-    bool known = false;
-    std::string cameraId;
-    for (auto& deviceInfo : mDevices) {
-        if (deviceInfo->mName == cameraDeviceName) {
-            Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
-            ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
-                    deviceStatusToString(newStatus),
-                    deviceStatusToString(mapToHidlCameraDeviceStatus(deviceInfo->mStatus)));
-            deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(newStatus);
-            // TODO: Handle device removal (NOT_PRESENT)
-            cameraId = deviceInfo->mId;
-            known = true;
-            deviceInfo->mIsDeviceAvailable =
-                (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT);
-            deviceInfo->mDeviceAvailableSignal.signal();
-            break;
-        }
-    }
-    // Previously unseen device; status must not be NOT_PRESENT
-    if (!known) {
-        if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
-            ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
-                mProviderName.c_str(), cameraDeviceName.c_str());
-            return BAD_VALUE;
-        }
-        addDevice(cameraDeviceName, newStatus, &cameraId);
-    } else if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
-        removeDevice(cameraId);
-    } else if (isExternalLazyHAL()) {
-        // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
-        // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
-        // notif. would overwrite it
-        return BAD_VALUE;
-    }
-    if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
-        ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
-                  __FUNCTION__, mProviderName.c_str());
-    }
-    *id = cameraId;
-    return OK;
-}
-
 hardware::Return<void> HidlProviderInfo::physicalCameraDeviceStatusChange(
         const hardware::hidl_string& cameraDeviceName,
         const hardware::hidl_string& physicalCameraDeviceName,
-        hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
-    sp<StatusListener> listener;
-    std::string id;
-    std::string physicalId;
-    std::lock_guard<std::mutex> lock(mInitLock);
-    CameraDeviceStatus newInternalStatus = hidlToInternalCameraDeviceStatus(newStatus);
-    if (!mInitialized) {
-        mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
-                physicalCameraDeviceName, newInternalStatus);
-        return hardware::Void();
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(mLock);
-
-        if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
-                physicalCameraDeviceName, newStatus)) {
-            return hardware::Void();
-        }
-
-        listener = mManager->getStatusListener();
-    }
-    // Call without lock held to allow reentrancy into provider manager
-    if (listener != nullptr) {
-        listener->onDeviceStatusChanged(String8(id.c_str()),
-                String8(physicalId.c_str()), newInternalStatus);
-    }
+        HalDeviceStatusType newStatus) {
+    physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+            HalToFrameworkCameraDeviceStatus(newStatus));
     return hardware::Void();
 }
 
-status_t HidlProviderInfo::physicalCameraDeviceStatusChangeLocked(
-            std::string* id, std::string* physicalId,
-            const hardware::hidl_string& cameraDeviceName,
-            const hardware::hidl_string& physicalCameraDeviceName,
-            hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
-    bool known = false;
-    std::string cameraId;
-    for (auto& deviceInfo : mDevices) {
-        if (deviceInfo->mName == cameraDeviceName) {
-            cameraId = deviceInfo->mId;
-            if (!deviceInfo->mIsLogicalCamera) {
-                ALOGE("%s: Invalid combination of camera id %s, physical id %s",
-                        __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
-                return BAD_VALUE;
-            }
-            if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
-                    physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
-                ALOGE("%s: Invalid combination of camera id %s, physical id %s",
-                        __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
-                return BAD_VALUE;
-            }
-            ALOGI("Camera device %s physical device %s status is now %s",
-                    cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
-                    deviceStatusToString(newStatus));
-            known = true;
-            break;
-        }
-    }
-    // Previously unseen device; status must not be NOT_PRESENT
-    if (!known) {
-        ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
-                mProviderName.c_str(), cameraDeviceName.c_str(),
-                physicalCameraDeviceName.c_str());
-        return BAD_VALUE;
-    }
-
-    *id = cameraId;
-    *physicalId = physicalCameraDeviceName.c_str();
-    return OK;
-}
-
 hardware::Return<void> HidlProviderInfo::torchModeStatusChange(
         const hardware::hidl_string& cameraDeviceName,
         hardware::camera::common::V1_0::TorchModeStatus newStatus) {
-    sp<StatusListener> listener;
-    SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
-    std::string id;
-    bool known = false;
-    {
-        // Hold mLock for accessing mDevices
-        std::lock_guard<std::mutex> lock(mLock);
-        for (auto& deviceInfo : mDevices) {
-            if (deviceInfo->mName == cameraDeviceName) {
-                ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
-                        torchStatusToString(newStatus));
-                id = deviceInfo->mId;
-                known = true;
-                systemCameraKind = deviceInfo->mSystemCameraKind;
-                if (hardware::camera::common::V1_0::TorchModeStatus::AVAILABLE_ON != newStatus) {
-                    mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
-                }
-                break;
-            }
-        }
-        if (!known) {
-            ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
-                    mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
-            return hardware::Void();
-        }
-        // no lock needed since listener is set up only once during
-        // CameraProviderManager initialization and then never changed till it is
-        // destructed.
-        listener = mManager->getStatusListener();
-     }
-    // Call without lock held to allow reentrancy into provider manager
-    // The problem with holding mLock here is that we
-    // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
-    // back into CameraProviderManager which might try to hold mLock again (eg:
-    // findDeviceInfo, which should be holding mLock while iterating through
-    // each provider's devices).
-    if (listener != nullptr) {
-        listener->onTorchStatusChanged(String8(id.c_str()),
-                hidlToInternalTorchModeStatus(newStatus), systemCameraKind);
-    }
+
+    torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
     return hardware::Void();
 }
 
@@ -836,7 +486,7 @@
     }
 
     return std::unique_ptr<DeviceInfo3>(
-        new HidlDeviceInfo3(name, tagId, id, minorVersion, hidlToInternalResourceCost(resourceCost),
+        new HidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
                 this, mProviderPublicCameraIds, cameraInterface));
 }
 
@@ -1474,91 +1124,4 @@
     return INVALID_OPERATION;
 }
 
-status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
-        const hardware::hidl_vec<common::V1_0::VendorTagSection>& vts,
-        sp<VendorTagDescriptor>& descriptor) {
-
-    int tagCount = 0;
-
-    for (size_t s = 0; s < vts.size(); s++) {
-        tagCount += vts[s].tags.size();
-    }
-
-    if (tagCount < 0 || tagCount > INT32_MAX) {
-        ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
-        return BAD_VALUE;
-    }
-
-    Vector<uint32_t> tagArray;
-    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
-            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
-
-
-    sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
-    desc->mTagCount = tagCount;
-
-    SortedVector<String8> sections;
-    KeyedVector<uint32_t, String8> tagToSectionMap;
-
-    int idx = 0;
-    for (size_t s = 0; s < vts.size(); s++) {
-        const common::V1_0::VendorTagSection& section = vts[s];
-        const char *sectionName = section.sectionName.c_str();
-        if (sectionName == NULL) {
-            ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
-            return BAD_VALUE;
-        }
-        String8 sectionString(sectionName);
-        sections.add(sectionString);
-
-        for (size_t j = 0; j < section.tags.size(); j++) {
-            uint32_t tag = section.tags[j].tagId;
-            if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
-                ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
-                return BAD_VALUE;
-            }
-
-            tagArray.editItemAt(idx++) = section.tags[j].tagId;
-
-            const char *tagName = section.tags[j].tagName.c_str();
-            if (tagName == NULL) {
-                ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
-                return BAD_VALUE;
-            }
-            desc->mTagToNameMap.add(tag, String8(tagName));
-            tagToSectionMap.add(tag, sectionString);
-
-            int tagType = (int) section.tags[j].tagType;
-            if (tagType < 0 || tagType >= NUM_TYPES) {
-                ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
-                return BAD_VALUE;
-            }
-            desc->mTagToTypeMap.add(tag, tagType);
-        }
-    }
-
-    desc->mSections = sections;
-
-    for (size_t i = 0; i < tagArray.size(); ++i) {
-        uint32_t tag = tagArray[i];
-        String8 sectionString = tagToSectionMap.valueFor(tag);
-
-        // Set up tag to section index map
-        ssize_t index = sections.indexOf(sectionString);
-        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
-        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
-
-        // Set up reverse mapping
-        ssize_t reverseIndex = -1;
-        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
-            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
-            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
-        }
-        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
-    }
-
-    descriptor = std::move(desc);
-    return OK;
-}
-
 } //namespace android
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index 0ba2aff..4181fea 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -21,25 +21,6 @@
 
 namespace android {
 
-/**
- * The vendor tag descriptor class that takes HIDL vendor tag information as
- * input. Not part of VendorTagDescriptor class because that class is used
- * in AIDL generated sources which don't have access to HIDL headers.
- */
-class HidlVendorTagDescriptor : public VendorTagDescriptor {
-public:
-    /**
-     * Create a VendorTagDescriptor object from the HIDL VendorTagSection
-     * vector.
-     *
-     * Returns OK on success, or a negative error code.
-     */
-    static status_t createDescriptorFromHidl(
-            const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
-            /*out*/
-            sp<VendorTagDescriptor>& descriptor);
-};
-
 struct HidlProviderInfo : public CameraProviderManager::ProviderInfo,
             virtual public hardware::camera::provider::V2_6::ICameraProviderCallback,
             virtual public hardware::hidl_death_recipient {
@@ -70,6 +51,8 @@
 
     virtual bool successfullyStartedProviderInterface() override;
 
+    virtual int64_t getDeviceState() override {return mDeviceState;};
+
     virtual status_t setUpVendorTags() override;
     virtual status_t notifyDeviceStateChange(int64_t) override;
 
@@ -129,24 +112,10 @@
 
  private:
 
-    status_t cameraDeviceStatusChangeLocked(
-                std::string* , const hardware::hidl_string& ,
-                hardware::camera::common::V1_0::CameraDeviceStatus );
-
-    status_t physicalCameraDeviceStatusChangeLocked(
-                std::string* , std::string* ,
-                const hardware::hidl_string& ,
-                const hardware::hidl_string& ,
-                hardware::camera::common::V1_0::CameraDeviceStatus );
-
-   status_t addDevice(const std::string& ,
-            hardware::camera::common::V1_0::CameraDeviceStatus ,
-            /*out*/ std::string *);
-
-    std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+    virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
             const metadata_vendor_id_t , const std::string &,
-            uint16_t );
-    status_t reCacheConcurrentStreamingCameraIdsLocked();
+            uint16_t ) override;
+    virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
 
     //Expects to have mLock locked
     status_t getConcurrentCameraIdsInternalLocked(
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index ca73e4c..3c98a5e 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -52,6 +52,7 @@
         "android.hardware.camera.provider@2.5",
         "android.hardware.camera.provider@2.6",
         "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V1-ndk",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index c3f0620..4928faf 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -44,6 +44,7 @@
         "android.hardware.camera.provider@2.5",
         "android.hardware.camera.provider@2.6",
         "android.hardware.camera.provider@2.7",
+        "android.hardware.camera.provider-V1-ndk",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 548fb0b..557591f 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -21,6 +21,7 @@
 #include "../api2/HeicCompositeStream.h"
 #include "android/hardware/camera/metadata/3.8/types.h"
 #include "common/CameraDeviceBase.h"
+#include "common/HalConversionsTemplated.h"
 #include "../CameraService.h"
 #include "device3/hidl/HidlCamera3Device.h"
 #include "device3/Camera3OutputStream.h"
@@ -504,110 +505,160 @@
     return binder::Status::ok();
 }
 
+aidl::android::hardware::graphics::common::PixelFormat mapToAidlPixelFormat(
+        int frameworkFormat) {
+    return (aidl::android::hardware::graphics::common::PixelFormat) frameworkFormat;
+}
+
+aidl::android::hardware::graphics::common::Dataspace mapToAidlDataspace(
+        android_dataspace dataSpace) {
+    return (aidl::android::hardware::graphics::common::Dataspace)dataSpace;
+}
+
+aidl::android::hardware::graphics::common::BufferUsage mapToAidlConsumerUsage(
+        uint64_t usage) {
+    return (aidl::android::hardware::graphics::common::BufferUsage)usage;
+}
+
+aidl::android::hardware::camera::device::StreamRotation
+mapToAidlStreamRotation(camera_stream_rotation_t rotation) {
+    switch (rotation) {
+        case CAMERA_STREAM_ROTATION_0:
+            return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+        case CAMERA_STREAM_ROTATION_90:
+            return aidl::android::hardware::camera::device::StreamRotation::ROTATION_90;
+        case CAMERA_STREAM_ROTATION_180:
+            return aidl::android::hardware::camera::device::StreamRotation::ROTATION_180;
+        case CAMERA_STREAM_ROTATION_270:
+            return aidl::android::hardware::camera::device::StreamRotation::ROTATION_270;
+    }
+    ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
+    return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+}
+
+status_t mapToAidlStreamConfigurationMode(
+        camera_stream_configuration_mode_t operationMode,
+        aidl::android::hardware::camera::device::StreamConfigurationMode *mode) {
+    using StreamConfigurationMode =
+            aidl::android::hardware::camera::device::StreamConfigurationMode;
+    if (mode == nullptr) return BAD_VALUE;
+    if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+        switch(operationMode) {
+            case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
+                *mode = StreamConfigurationMode::NORMAL_MODE;
+                break;
+            case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+                *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
+                break;
+            default:
+                ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
+                return BAD_VALUE;
+        }
+    } else {
+        *mode = static_cast<StreamConfigurationMode>(operationMode);
+    }
+    return OK;
+}
+
 void mapStreamInfo(const OutputStreamInfo &streamInfo,
             camera3::camera_stream_rotation_t rotation, String8 physicalId,
-            int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
+            int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
     if (stream == nullptr) {
         return;
     }
 
-    stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
-    stream->v3_7.v3_4.v3_2.width = streamInfo.width;
-    stream->v3_7.v3_4.v3_2.height = streamInfo.height;
-    stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
+    stream->streamType = aidl::android::hardware::camera::device::StreamType::OUTPUT;
+    stream->width = streamInfo.width;
+    stream->height = streamInfo.height;
+    stream->format = mapToAidlPixelFormat(streamInfo.format);
     auto u = streamInfo.consumerUsage;
     camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
-    stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
-    stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
-    stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
-    stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
-    stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
-    stream->v3_7.v3_4.bufferSize = 0;
-    stream->v3_7.groupId = groupId;
-    stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
-
+    stream->usage = mapToAidlConsumerUsage(u);
+    stream->dataSpace = mapToAidlDataspace(streamInfo.dataSpace);
+    stream->rotation = mapToAidlStreamRotation(rotation);
+    stream->id = -1; // Invalid stream id
+    stream->physicalCameraId = std::string(physicalId.string());
+    stream->bufferSize = 0;
+    stream->groupId = groupId;
+    stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
     size_t idx = 0;
+    using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
     for (auto mode : streamInfo.sensorPixelModesUsed) {
-        stream->v3_7.sensorPixelModesUsed[idx++] =
-                static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+        stream->sensorPixelModesUsed[idx++] =
+                static_cast<SensorPixelMode>(mode);
     }
-    stream->dynamicRangeProfile =
-        static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
-                streamInfo.dynamicRangeProfile);
-    stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
-            streamInfo.streamUseCase);
+    using DynamicRangeProfile =
+            aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
+    stream->dynamicRangeProfile = static_cast<DynamicRangeProfile>(streamInfo.dynamicRangeProfile);
+    using StreamUseCases =
+            aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
+    stream->useCase = static_cast<StreamUseCases>(streamInfo.streamUseCase);
 }
 
-binder::Status checkPhysicalCameraId(
-        const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
-        const String8 &logicalCameraId) {
-    if (physicalCameraId.size() == 0) {
-        return binder::Status::ok();
+status_t
+convertAidlToHidl38StreamCombination(
+        const aidl::android::hardware::camera::device::StreamConfiguration &aidl,
+        hardware::camera::device::V3_8::StreamConfiguration &hidl) {
+    hidl.operationMode =
+        static_cast<hardware::camera::device::V3_2::StreamConfigurationMode>(aidl.operationMode);
+    if (aidl.streamConfigCounter < 0) {
+        return BAD_VALUE;
     }
-    if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
-        physicalCameraId.string()) == physicalCameraIds.end()) {
-        String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
-                logicalCameraId.string(), physicalCameraId.string());
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
-    }
-    return binder::Status::ok();
-}
+    hidl.streamConfigCounter = static_cast<uint32_t>(aidl.streamConfigCounter);
+    hidl.multiResolutionInputImage = aidl.multiResolutionInputImage;
+    hidl.sessionParams = aidl.sessionParams.metadata;
+    hidl.streams.resize(aidl.streams.size());
+    size_t i = 0;
+    for (const auto &stream : aidl.streams) {
+        //hidlv3_8
+        hidl.streams[i].dynamicRangeProfile =
+                static_cast<
+                        CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
+                                (stream.dynamicRangeProfile);
+        hidl.streams[i].useCase =
+                static_cast<
+                        CameraMetadataEnumAndroidScalerAvailableStreamUseCases>
+                                (stream.useCase);
 
-binder::Status checkSurfaceType(size_t numBufferProducers,
-        bool deferredConsumer, int surfaceType)  {
-    if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
-        ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
-                __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
-    } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
-        ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
-    }
-
-    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
-            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
-
-    if (deferredConsumer && !validSurfaceType) {
-        ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
-    }
-
-    return binder::Status::ok();
-}
-
-binder::Status checkOperatingMode(int operatingMode,
-        const CameraMetadata &staticInfo, const String8 &cameraId) {
-    if (operatingMode < 0) {
-        String8 msg = String8::format(
-            "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
-        ALOGE("%s: %s", __FUNCTION__, msg.string());
-        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                msg.string());
-    }
-
-    bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
-    if (isConstrainedHighSpeed) {
-        camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
-        bool isConstrainedHighSpeedSupported = false;
-        for(size_t i = 0; i < entry.count; ++i) {
-            uint8_t capability = entry.data.u8[i];
-            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
-                isConstrainedHighSpeedSupported = true;
-                break;
-            }
+        // hidl v3_7
+        hidl.streams[i].v3_7.groupId = stream.groupId;
+        hidl.streams[i].v3_7.sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
+        size_t j = 0;
+        for (const auto &mode : stream.sensorPixelModesUsed) {
+            hidl.streams[i].v3_7.sensorPixelModesUsed[j] =
+                    static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+            j++;
         }
-        if (!isConstrainedHighSpeedSupported) {
-            String8 msg = String8::format(
-                "Camera %s: Try to create a constrained high speed configuration on a device"
-                " that doesn't support it.", cameraId.string());
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                    msg.string());
-        }
-    }
 
-    return binder::Status::ok();
+        //hidl v3_4
+        hidl.streams[i].v3_7.v3_4.physicalCameraId = stream.physicalCameraId;
+
+        if (stream.bufferSize < 0) {
+            return BAD_VALUE;
+        }
+        hidl.streams[i].v3_7.v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
+
+        // hild v3_2
+        hidl.streams[i].v3_7.v3_4.v3_2.id = stream.id;
+        hidl.streams[i].v3_7.v3_4.v3_2.format =
+                static_cast<hardware::graphics::common::V1_0::PixelFormat>(stream.format);
+
+        if (stream.width < 0 || stream.height < 0) {
+            return BAD_VALUE;
+        }
+        hidl.streams[i].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
+        hidl.streams[i].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
+        hidl.streams[i].v3_7.v3_4.v3_2.usage =
+                static_cast<hardware::camera::device::V3_2::BufferUsageFlags>(stream.usage);
+        hidl.streams[i].v3_7.v3_4.v3_2.streamType =
+                static_cast<hardware::camera::device::V3_2::StreamType>(stream.streamType);
+        hidl.streams[i].v3_7.v3_4.v3_2.dataSpace =
+                static_cast<hardware::camera::device::V3_2::DataspaceFlags>(stream.dataSpace);
+        hidl.streams[i].v3_7.v3_4.v3_2.rotation =
+                static_cast<hardware::camera::device::V3_2::StreamRotation>(stream.rotation);
+        i++;
+    }
+    return OK;
 }
 
 binder::Status
@@ -615,9 +666,10 @@
         const SessionConfiguration& sessionConfiguration,
         const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
         metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
-        hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+        aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
         bool overrideForPerfClass, bool *earlyExit) {
-
+    using SensorPixelMode =
+            aidl::android::hardware::camera::metadata::SensorPixelMode;
     auto operatingMode = sessionConfiguration.getOperatingMode();
     binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
     if (!res.isOk()) {
@@ -630,7 +682,7 @@
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
     }
     *earlyExit = false;
-    auto ret = HidlCamera3Device::mapToStreamConfigurationMode(
+    auto ret = mapToAidlStreamConfigurationMode(
             static_cast<camera_stream_configuration_mode_t> (operatingMode),
             /*out*/ &streamConfiguration.operationMode);
     if (ret != OK) {
@@ -651,19 +703,25 @@
     streamConfiguration.streams.resize(streamCount);
     size_t streamIdx = 0;
     if (isInputValid) {
-        hardware::hidl_vec<CameraMetadataEnumAndroidSensorPixelMode> defaultSensorPixelModes;
+        std::vector<SensorPixelMode> defaultSensorPixelModes;
         defaultSensorPixelModes.resize(1);
         defaultSensorPixelModes[0] =
-                static_cast<CameraMetadataEnumAndroidSensorPixelMode>(
-                        ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
-        streamConfiguration.streams[streamIdx++].v3_7 = {{{/*streamId*/0,
-                hardware::camera::device::V3_2::StreamType::INPUT,
-                static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
-                static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
-                HidlCamera3Device::mapToPixelFormat(sessionConfiguration.getInputFormat()),
-                /*usage*/ 0, HAL_DATASPACE_UNKNOWN,
-                hardware::camera::device::V3_2::StreamRotation::ROTATION_0},
-                /*physicalId*/ nullptr, /*bufferSize*/0}, /*groupId*/-1, defaultSensorPixelModes};
+                static_cast<SensorPixelMode>(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
+        aidl::android::hardware::camera::device::Stream stream;
+        stream.id = 0;
+        stream.streamType =  aidl::android::hardware::camera::device::StreamType::INPUT;
+        stream.width = static_cast<uint32_t> (sessionConfiguration.getInputWidth());
+        stream.height =  static_cast<uint32_t> (sessionConfiguration.getInputHeight());
+        stream.format = mapToAidlPixelFormat(sessionConfiguration.getInputFormat());
+        stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0);
+        stream.dataSpace =
+              static_cast<aidl::android::hardware::graphics::common::Dataspace>(
+                      HAL_DATASPACE_UNKNOWN);
+        stream.rotation = aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+        stream.bufferSize = 0;
+        stream.groupId = -1;
+        stream.sensorPixelModesUsed = defaultSensorPixelModes;
+        streamConfiguration.streams[streamIdx++] = stream;
         streamConfiguration.multiResolutionInputImage =
                 sessionConfiguration.inputIsMultiResolution();
     }
@@ -789,6 +847,138 @@
     return binder::Status::ok();
 }
 
+void mapStreamInfo(const OutputStreamInfo &streamInfo,
+            camera3::camera_stream_rotation_t rotation, String8 physicalId,
+            int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
+    if (stream == nullptr) {
+        return;
+    }
+
+    stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
+    stream->v3_7.v3_4.v3_2.width = streamInfo.width;
+    stream->v3_7.v3_4.v3_2.height = streamInfo.height;
+    stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
+    auto u = streamInfo.consumerUsage;
+    camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
+    stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
+    stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
+    stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
+    stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
+    stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
+    stream->v3_7.v3_4.bufferSize = 0;
+    stream->v3_7.groupId = groupId;
+    stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
+
+    size_t idx = 0;
+    for (auto mode : streamInfo.sensorPixelModesUsed) {
+        stream->v3_7.sensorPixelModesUsed[idx++] =
+                static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+    }
+    stream->dynamicRangeProfile =
+        static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
+                streamInfo.dynamicRangeProfile);
+    stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
+            streamInfo.streamUseCase);
+}
+
+binder::Status checkPhysicalCameraId(
+        const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
+        const String8 &logicalCameraId) {
+    if (physicalCameraId.size() == 0) {
+        return binder::Status::ok();
+    }
+    if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
+        physicalCameraId.string()) == physicalCameraIds.end()) {
+        String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
+                logicalCameraId.string(), physicalCameraId.string());
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+    }
+    return binder::Status::ok();
+}
+
+binder::Status checkSurfaceType(size_t numBufferProducers,
+        bool deferredConsumer, int surfaceType)  {
+    if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
+        ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
+                __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
+    } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
+        ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
+    }
+
+    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
+            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
+
+    if (deferredConsumer && !validSurfaceType) {
+        ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
+    }
+
+    return binder::Status::ok();
+}
+
+binder::Status checkOperatingMode(int operatingMode,
+        const CameraMetadata &staticInfo, const String8 &cameraId) {
+    if (operatingMode < 0) {
+        String8 msg = String8::format(
+            "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                msg.string());
+    }
+
+    bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
+    if (isConstrainedHighSpeed) {
+        camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+        bool isConstrainedHighSpeedSupported = false;
+        for(size_t i = 0; i < entry.count; ++i) {
+            uint8_t capability = entry.data.u8[i];
+            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
+                isConstrainedHighSpeedSupported = true;
+                break;
+            }
+        }
+        if (!isConstrainedHighSpeedSupported) {
+            String8 msg = String8::format(
+                "Camera %s: Try to create a constrained high speed configuration on a device"
+                " that doesn't support it.", cameraId.string());
+            ALOGE("%s: %s", __FUNCTION__, msg.string());
+            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                    msg.string());
+        }
+    }
+
+    return binder::Status::ok();
+}
+
+binder::Status
+convertToHALStreamCombination(
+        const SessionConfiguration& sessionConfiguration,
+        const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+        metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+        hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+        bool overrideForPerfClass, bool *earlyExit) {
+    aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
+    auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
+            getMetadata, physicalCameraIds, aidlStreamConfiguration, overrideForPerfClass,
+            earlyExit);
+    if (!ret.isOk()) {
+        return ret;
+    }
+    if (earlyExit != nullptr && *earlyExit) {
+        return binder::Status::ok();
+    }
+
+    if (convertAidlToHidl38StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                "Invalid AIDL->HIDL3.8 conversion");
+    }
+
+    return binder::Status::ok();
+}
+
 static bool inStreamConfigurationMap(int format, int width, int height,
         const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
     auto scs = sm.find(format);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 8dfc11d..39ba079 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -22,6 +22,7 @@
 #include <camera/camera2/SessionConfiguration.h>
 #include <camera/camera2/SubmitInfo.h>
 #include <android/hardware/camera/device/3.8/types.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
@@ -115,6 +116,10 @@
 
 bool isStreamUseCaseSupported(int streamUseCase, const CameraMetadata &deviceInfo);
 
+void mapStreamInfo(const OutputStreamInfo &streamInfo,
+        camera3::camera_stream_rotation_t rotation, String8 physicalId,
+        int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/);
+
 // Check that the physicalCameraId passed in is spported by the camera
 // device.
 binder::Status checkPhysicalCameraId(
@@ -145,6 +150,14 @@
         hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
         const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38);
 
+binder::Status
+convertToHALStreamCombination(
+    const SessionConfiguration& sessionConfiguration,
+    const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+    metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+    aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
+    bool overrideForPerfClass, bool *earlyExit);
+
 // Utility function to convert a V3_7::StreamConfiguration to
 // V3_4::StreamConfiguration. Return false if the original V3_7 configuration cannot
 // be used by older version HAL.