Merge changes I2ca96002,I8f9c076e into main

* changes:
  Add the abstraction layer for the camera classes
  Add EVS Camera Device Type to the Default Implementation
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
index 1d5fe77..37a17dc 100644
--- a/automotive/evs/aidl/impl/default/include/ConfigManager.h
+++ b/automotive/evs/aidl/impl/default/include/ConfigManager.h
@@ -25,8 +25,10 @@
 
 #include <tinyxml2.h>
 
+#include <limits>
 #include <string>
 #include <string_view>
+#include <type_traits>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
@@ -54,6 +56,15 @@
     /* Camera device's capabilities and metadata */
     class CameraInfo {
       public:
+        enum class DeviceType : std::int32_t {
+            NONE = 0,
+            MOCK = 1,
+            V4L2 = 2,
+            VIDEO = 3,
+
+            UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
+        };
+
         CameraInfo() : characteristics(nullptr) {}
 
         virtual ~CameraInfo();
@@ -69,6 +80,10 @@
             return characteristics != nullptr;
         }
 
+        static DeviceType deviceTypeFromSV(const std::string_view sv);
+
+        DeviceType deviceType{DeviceType::NONE};
+
         /*
          * List of supported controls that the primary client can program.
          * Paraemters are stored with its valid range
diff --git a/automotive/evs/aidl/impl/default/include/EvsCameraBase.h b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
new file mode 100644
index 0000000..c3e9dfc
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsCameraBase : public evs::BnEvsCamera {
+  private:
+    using Base = evs::BnEvsCamera;
+    using Self = EvsCameraBase;
+
+  public:
+    using Base::Base;
+
+    ~EvsCameraBase() override = default;
+
+    virtual void shutdown() = 0;
+
+  protected:
+    // This is used for the derived classes and it prevents constructors from direct access
+    // while it allows this class to be instantiated via ndk::SharedRefBase::make<>.
+    struct Sigil {
+        explicit Sigil() = default;
+    };
+};
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
index 3897b4e..9dcc774 100644
--- a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
+++ b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
@@ -17,8 +17,8 @@
 #pragma once
 
 #include "ConfigManager.h"
+#include "EvsCameraBase.h"
 #include "EvsGlDisplay.h"
-#include "EvsMockCamera.h"
 
 #include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
 #include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
@@ -73,7 +73,7 @@
   private:
     struct CameraRecord {
         evs::CameraDesc desc;
-        std::weak_ptr<EvsMockCamera> activeInstance;
+        std::weak_ptr<EvsCameraBase> activeInstance;
 
         CameraRecord(const char* cameraId) : desc() { desc.id = cameraId; }
     };
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
index 7e010a2..c7b9e0f 100644
--- a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
@@ -17,8 +17,8 @@
 #pragma once
 
 #include "ConfigManager.h"
+#include "EvsCameraBase.h"
 
-#include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
 #include <aidl/android/hardware/automotive/evs/CameraDesc.h>
 #include <aidl/android/hardware/automotive/evs/CameraParam.h>
@@ -36,14 +36,7 @@
 
 namespace aidl::android::hardware::automotive::evs::implementation {
 
-class EvsMockCamera : public evs::BnEvsCamera {
-    // This prevents constructors from direct access while it allows this class to
-    // be instantiated via ndk::SharedRefBase::make<>.
-  private:
-    struct Sigil {
-        explicit Sigil() = default;
-    };
-
+class EvsMockCamera : public EvsCameraBase {
   public:
     // Methods from ::android::hardware::automotive::evs::IEvsCamera follow.
     ndk::ScopedAStatus doneWithFrame(const std::vector<evs::BufferDesc>& buffers) override;
@@ -81,7 +74,9 @@
     EvsMockCamera& operator=(const EvsMockCamera&) = delete;
 
     virtual ~EvsMockCamera() override;
-    void shutdown();
+
+    // Methods from EvsCameraBase follow.
+    void shutdown() override;
 
     const evs::CameraDesc& getDesc() { return mDescription; }
 
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
index da791ed..ba4cdc0 100644
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -40,6 +40,18 @@
 std::string_view ConfigManager::sConfigOverridePath =
         "/vendor/etc/automotive/evs/evs_configuration_override.xml";
 
+ConfigManager::CameraInfo::DeviceType ConfigManager::CameraInfo::deviceTypeFromSV(
+        const std::string_view sv) {
+    using namespace std::string_view_literals;
+    static const std::unordered_map<std::string_view, DeviceType> nameToType = {
+            {"mock"sv, DeviceType::MOCK},
+            {"v4l2"sv, DeviceType::V4L2},
+            {"video"sv, DeviceType::VIDEO},
+    };
+    const auto search = nameToType.find(sv);
+    return search == nameToType.end() ? DeviceType::UNKNOWN : search->second;
+}
+
 void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
     const XMLElement* curElem = rootElem;
 
@@ -128,6 +140,10 @@
         return false;
     }
 
+    if (const auto typeAttr = aDeviceElem->FindAttribute("type")) {
+        aCamera->deviceType = CameraInfo::deviceTypeFromSV(typeAttr->Value());
+    }
+
     /* size information to allocate camera_metadata_t */
     size_t totalEntries = 0;
     size_t totalDataSize = 0;
diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
index 5178958..ec4b18f 100644
--- a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
@@ -17,6 +17,7 @@
 #include "EvsEnumerator.h"
 
 #include "ConfigManager.h"
+#include "EvsCameraBase.h"
 #include "EvsGlDisplay.h"
 #include "EvsMockCamera.h"
 
@@ -243,7 +244,7 @@
     }
 
     // Has this camera already been instantiated by another caller?
-    std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+    std::shared_ptr<EvsCameraBase> pActiveCamera = pRecord->activeInstance.lock();
     if (pActiveCamera) {
         LOG(WARNING) << "Killing previous camera because of new caller";
         closeCamera(pActiveCamera);
@@ -253,12 +254,27 @@
     if (!sConfigManager) {
         pActiveCamera = EvsMockCamera::Create(id.data());
     } else {
-        pActiveCamera = EvsMockCamera::Create(id.data(), sConfigManager->getCameraInfo(id), &cfg);
+        auto& cameraInfo = sConfigManager->getCameraInfo(id);
+        switch (cameraInfo->deviceType) {
+            using DeviceType = ConfigManager::CameraInfo::DeviceType;
+
+            // Default to MOCK for backward compatibility.
+            case DeviceType::NONE:
+            case DeviceType::MOCK:
+                pActiveCamera = EvsMockCamera::Create(id.data(), cameraInfo, &cfg);
+                break;
+
+            default:
+                LOG(ERROR) << __func__ << ": camera device type "
+                           << static_cast<std::int32_t>(cameraInfo->deviceType)
+                           << " is not supported.";
+                break;
+        }
     }
 
     pRecord->activeInstance = pActiveCamera;
     if (!pActiveCamera) {
-        LOG(ERROR) << "Failed to create new EvsMockCamera object for " << id;
+        LOG(ERROR) << "Failed to create new EVS camera object for " << id;
         return ScopedAStatus::fromServiceSpecificError(
                 static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
     }
@@ -445,7 +461,7 @@
     if (!pRecord) {
         LOG(ERROR) << "Asked to close a camera whose name isn't recognized";
     } else {
-        std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+        std::shared_ptr<EvsCameraBase> pActiveCamera = pRecord->activeInstance.lock();
         if (!pActiveCamera) {
             LOG(WARNING) << "Somehow a camera is being destroyed "
                          << "when the enumerator didn't know one existed";