Camera: plumb external camera API1 support

And also some refactoring to unify external camera
config file logics.

Bug: 72261912
Change-Id: If83d779c57540809bdaa58a5a32cf4ade734fafe
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 569acfd..61b8921 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -44,9 +44,10 @@
 
 } // anonymous namespace
 
-ExternalCameraDevice::ExternalCameraDevice(const std::string& cameraId) :
+ExternalCameraDevice::ExternalCameraDevice(
+            const std::string& cameraId, const ExternalCameraConfig& cfg) :
         mCameraId(cameraId),
-        mCfg(ExternalCameraDeviceConfig::loadFromCfg()) {
+        mCfg(cfg) {
 
     status_t ret = initCameraCharacteristics();
     if (ret != OK) {
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 51bfe36..74fd7f4 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -55,7 +55,7 @@
 
 ExternalCameraDeviceSession::ExternalCameraDeviceSession(
         const sp<ICameraDeviceCallback>& callback,
-        const ExternalCameraDeviceConfig& cfg,
+        const ExternalCameraConfig& cfg,
         const std::vector<SupportedV4L2Format>& sortedFormats,
         const CroppingType& croppingType,
         const common::V1_0::helper::CameraMetadata& chars,
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 212573a..80f296c 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -30,14 +30,6 @@
 namespace V3_4 {
 namespace implementation {
 
-namespace {
-    const int  kDefaultJpegBufSize = 5 << 20; // 5MB
-    const int  kDefaultNumVideoBuffer = 4;
-    const int  kDefaultNumStillBuffer = 2;
-} // anonymous namespace
-
-const char* ExternalCameraDeviceConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
-
 V4L2Frame::V4L2Frame(
         uint32_t w, uint32_t h, uint32_t fourcc,
         int bufIdx, int fd, uint32_t dataSize, uint64_t offset) :
@@ -148,10 +140,32 @@
     return 0;
 }
 
+bool isAspectRatioClose(float ar1, float ar2) {
+    const float kAspectRatioMatchThres = 0.025f; // This threshold is good enough to distinguish
+                                                // 4:3/16:9/20:9
+                                                // 1.33 / 1.78 / 2
+    return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
+}
 
-ExternalCameraDeviceConfig ExternalCameraDeviceConfig::loadFromCfg(const char* cfgPath) {
+}  // namespace implementation
+}  // namespace V3_4
+}  // namespace device
+
+
+namespace external {
+namespace common {
+
+namespace {
+    const int  kDefaultJpegBufSize = 5 << 20; // 5MB
+    const int  kDefaultNumVideoBuffer = 4;
+    const int  kDefaultNumStillBuffer = 2;
+} // anonymous namespace
+
+const char* ExternalCameraConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
+
+ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
     using namespace tinyxml2;
-    ExternalCameraDeviceConfig ret;
+    ExternalCameraConfig ret;
 
     XMLDocument configXml;
     XMLError err = configXml.LoadFile(cfgPath);
@@ -169,6 +183,29 @@
         return ret;
     }
 
+    XMLElement *providerCfg = extCam->FirstChildElement("Provider");
+    if (providerCfg == nullptr) {
+        ALOGI("%s: no external camera provider config specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement *ignore = providerCfg->FirstChildElement("ignore");
+    if (ignore == nullptr) {
+        ALOGI("%s: no internal ignored device specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement *id = ignore->FirstChildElement("id");
+    while (id != nullptr) {
+        const char* text = id->GetText();
+        if (text != nullptr) {
+            ret.mInternalDevices.insert(text);
+            ALOGI("%s: device %s will be ignored by external camera provider",
+                    __FUNCTION__, text);
+        }
+        id = id->NextSiblingElement("id");
+    }
+
     XMLElement *deviceCfg = extCam->FirstChildElement("Device");
     if (deviceCfg == nullptr) {
         ALOGI("%s: no external camera device config specified", __FUNCTION__);
@@ -226,7 +263,7 @@
         ret.fpsLimits = limits;
     }
 
-    ALOGI("%s: external camera cfd loaded: maxJpgBufSize %d,"
+    ALOGI("%s: external camera cfg loaded: maxJpgBufSize %d,"
             " num video buffers %d, num still buffers %d",
             __FUNCTION__, ret.maxJpegBufSize,
             ret.numVideoBuffers, ret.numStillBuffers);
@@ -237,7 +274,7 @@
     return ret;
 }
 
-ExternalCameraDeviceConfig::ExternalCameraDeviceConfig() :
+ExternalCameraConfig::ExternalCameraConfig() :
         maxJpegBufSize(kDefaultJpegBufSize),
         numVideoBuffers(kDefaultNumVideoBuffer),
         numStillBuffers(kDefaultNumStillBuffer) {
@@ -247,16 +284,9 @@
     fpsLimits.push_back({/*Size*/{4096, 3072}, /*FPS upper bound*/5.0});
 }
 
-bool isAspectRatioClose(float ar1, float ar2) {
-    const float kAspectRatioMatchThres = 0.025f; // This threshold is good enough to distinguish
-                                                // 4:3/16:9/20:9
-                                                // 1.33 / 1.78 / 2
-    return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
-}
 
-}  // namespace implementation
-}  // namespace V3_4
-}  // namespace device
+}  // namespace common
+}  // namespace external
 }  // namespace camera
 }  // namespace hardware
 }  // namespace android
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index fabf26a..cced3f7 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -67,6 +67,9 @@
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
 using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::Size;
+using ::android::hardware::camera::external::common::SizeHasher;
 using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -84,7 +87,7 @@
 struct ExternalCameraDeviceSession : public virtual RefBase {
 
     ExternalCameraDeviceSession(const sp<ICameraDeviceCallback>&,
-            const ExternalCameraDeviceConfig& cfg,
+            const ExternalCameraConfig& cfg,
             const std::vector<SupportedV4L2Format>& sortedFormats,
             const CroppingType& croppingType,
             const common::V1_0::helper::CameraMetadata& chars,
@@ -277,7 +280,7 @@
 
     mutable Mutex mLock; // Protect all private members except otherwise noted
     const sp<ICameraDeviceCallback> mCallback;
-    const ExternalCameraDeviceConfig mCfg;
+    const ExternalCameraConfig& mCfg;
     const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
     const std::vector<SupportedV4L2Format> mSupportedFormats;
     const CroppingType mCroppingType;
@@ -293,7 +296,7 @@
 
     bool mV4l2Streaming = false;
     SupportedV4L2Format mV4l2StreamingFmt;
-    size_t mV4L2BufferCount;
+    size_t mV4L2BufferCount = 0;
 
     static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
     std::mutex mV4l2BufferLock; // protect the buffer count and condition below
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index ef4b41c..5880469 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -38,6 +38,8 @@
 using ::android::hardware::camera::common::V1_0::CameraResourceCost;
 using ::android::hardware::camera::common::V1_0::TorchMode;
 using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::Size;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::hidl_vec;
@@ -54,7 +56,7 @@
     // be multiple CameraDevice trying to access the same physical camera.  Also, provider will have
     // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
     // camera is detached.
-    ExternalCameraDevice(const std::string& cameraId);
+    ExternalCameraDevice(const std::string& cameraId, const ExternalCameraConfig& cfg);
     ~ExternalCameraDevice();
 
     // Caller must use this method to check if CameraDevice ctor failed
@@ -95,7 +97,7 @@
     Mutex mLock;
     bool mInitFailed = false;
     std::string mCameraId;
-    const ExternalCameraDeviceConfig mCfg;
+    const ExternalCameraConfig& mCfg;
     std::vector<SupportedV4L2Format> mSupportedFormats;
     CroppingType mCroppingType;
 
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index 849f947..e56160a 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -21,6 +21,7 @@
 #include "utils/LightRefBase.h"
 #include <mutex>
 #include <vector>
+#include <unordered_set>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
 
 using android::hardware::graphics::mapper::V2_0::IMapper;
@@ -29,6 +30,60 @@
 namespace android {
 namespace hardware {
 namespace camera {
+
+namespace external {
+namespace common {
+
+struct Size {
+    uint32_t width;
+    uint32_t height;
+
+    bool operator==(const Size& other) const {
+        return (width == other.width && height == other.height);
+    }
+};
+
+struct SizeHasher {
+    size_t operator()(const Size& sz) const {
+        size_t result = 1;
+        result = 31 * result + sz.width;
+        result = 31 * result + sz.height;
+        return result;
+    }
+};
+
+struct ExternalCameraConfig {
+    static const char* kDefaultCfgPath;
+    static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
+
+    // List of internal V4L2 video nodes external camera HAL must ignore.
+    std::unordered_set<std::string> mInternalDevices;
+
+    // Maximal size of a JPEG buffer, in bytes
+    uint32_t maxJpegBufSize;
+
+    // Maximum Size that can sustain 30fps streaming
+    Size maxVideoSize;
+
+    // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
+    uint32_t numVideoBuffers;
+
+    // Size of v4l2 buffer queue when streaming > kMaxVideoSize
+    uint32_t numStillBuffers;
+
+    struct FpsLimitation {
+        Size size;
+        float fpsUpperBound;
+    };
+    std::vector<FpsLimitation> fpsLimits;
+
+private:
+    ExternalCameraConfig();
+};
+
+} // common
+} // external
+
 namespace device {
 namespace V3_4 {
 namespace implementation {
@@ -85,50 +140,6 @@
     VERTICAL = 1
 };
 
-struct Size {
-    uint32_t width;
-    uint32_t height;
-
-    bool operator==(const Size& other) const {
-        return (width == other.width && height == other.height);
-    }
-};
-
-struct SizeHasher {
-    size_t operator()(const Size& sz) const {
-        size_t result = 1;
-        result = 31 * result + sz.width;
-        result = 31 * result + sz.height;
-        return result;
-    }
-};
-
-struct ExternalCameraDeviceConfig {
-    static const char* kDefaultCfgPath;
-    static ExternalCameraDeviceConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
-
-    // Maximal size of a JPEG buffer, in bytes
-    uint32_t maxJpegBufSize;
-
-    // Maximum Size that can sustain 30fps streaming
-    Size maxVideoSize;
-
-    // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
-    uint32_t numVideoBuffers;
-
-    // Size of v4l2 buffer queue when streaming > kMaxVideoSize
-    uint32_t numStillBuffers;
-
-    struct FpsLimitation {
-        Size size;
-        float fpsUpperBound;
-    };
-    std::vector<FpsLimitation> fpsLimits;
-
-private:
-    ExternalCameraDeviceConfig();
-};
-
 // Aspect ratio is defined as width/height here and ExternalCameraDevice
 // will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0)
 #define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height)