Reapply "GCH: Check for physical stream use cases for physical st..." am: 09f2ecc89d

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/google/camera/+/27181586

Change-Id: I28360019825f49d958501a35bb42c3292e89c9dc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/common/hal/google_camera_hal/camera_device.cc b/common/hal/google_camera_hal/camera_device.cc
index c6e53dd..831a506 100644
--- a/common/hal/google_camera_hal/camera_device.cc
+++ b/common/hal/google_camera_hal/camera_device.cc
@@ -176,14 +176,26 @@
     return res;
   }
 
-  res = utils::GetStreamUseCases(static_metadata.get(), &stream_use_cases_);
+  res = utils::GetStreamUseCases(
+      static_metadata.get(),
+      &camera_id_to_stream_use_cases_[camera_device_hwl_->GetCameraId()]);
   if (res != OK) {
-    ALOGE("%s: Getting stream use cases failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
+    ALOGE(
+        "%s: Initializing logical stream use case for camera id %u failed: "
+        "%s(%d)",
+        __FUNCTION__, camera_device_hwl_->GetCameraId(), strerror(-res), res);
     return res;
   }
+  res = utils::GetPhysicalCameraStreamUseCases(camera_device_hwl_.get(),
+                                               &camera_id_to_stream_use_cases_);
 
-  return OK;
+  if (res != OK) {
+    ALOGE(
+        "%s: Initializing physical stream use case for camera id %u failed: "
+        "%s(%d)",
+        __FUNCTION__, camera_device_hwl_->GetCameraId(), strerror(-res), res);
+  }
+  return res;
 }
 
 status_t CameraDevice::GetResourceCost(CameraResourceCost* cost) {
@@ -355,7 +367,8 @@
 
 bool CameraDevice::IsStreamCombinationSupported(
     const StreamConfiguration& stream_config, bool /*check_settings*/) {
-  if (!utils::IsStreamUseCaseSupported(stream_config, stream_use_cases_)) {
+  if (!utils::IsStreamUseCaseSupported(stream_config, public_camera_id_,
+                                       camera_id_to_stream_use_cases_)) {
     return false;
   }
 
diff --git a/common/hal/google_camera_hal/camera_device.h b/common/hal/google_camera_hal/camera_device.h
index df48391..85ef75f 100644
--- a/common/hal/google_camera_hal/camera_device.h
+++ b/common/hal/google_camera_hal/camera_device.h
@@ -17,6 +17,8 @@
 #ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_CAMERA_DEVICE_H_
 #define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_CAMERA_DEVICE_H_
 
+#include <map>
+
 #include "camera_buffer_allocator_hwl.h"
 #include "camera_device_hwl.h"
 #include "camera_device_session.h"
@@ -123,7 +125,7 @@
   // Opened library handles that should be closed on destruction
   std::vector<void*> external_capture_session_lib_handles_;
   // Stream use cases supported by this camera device
-  std::set<int64_t> stream_use_cases_;
+  std::map<uint32_t, std::set<int64_t>> camera_id_to_stream_use_cases_;
 
   const std::vector<std::string>* configure_streams_libs_ = nullptr;
 };
diff --git a/common/hal/google_camera_hal/camera_device_session.cc b/common/hal/google_camera_hal/camera_device_session.cc
index 654ea27..7784567 100644
--- a/common/hal/google_camera_hal/camera_device_session.cc
+++ b/common/hal/google_camera_hal/camera_device_session.cc
@@ -410,13 +410,24 @@
     return res;
   }
 
-  res = utils::GetStreamUseCases(characteristics.get(), &stream_use_cases_);
+  res = utils::GetStreamUseCases(
+      characteristics.get(),
+      &camera_id_to_stream_use_cases_[device_session_hwl_->GetCameraId()]);
   if (res != OK) {
-    ALOGE("%s: Initializing stream use case failed: %s(%d)", __FUNCTION__,
-          strerror(-res), res);
+    ALOGE("%s: Initializing stream use case failed: %s(%d) for camera id %u",
+          __FUNCTION__, strerror(-res), res, device_session_hwl_->GetCameraId());
     return res;
   }
 
+  res = utils::GetPhysicalCameraStreamUseCases(device_session_hwl_.get(),
+                                               &camera_id_to_stream_use_cases_);
+  if (res != OK) {
+    ALOGE(
+        "%s: Initializing physical stream use cases failed: %s(%d) for camera "
+        "id %u",
+        __FUNCTION__, strerror(-res), res, device_session_hwl_->GetCameraId());
+    return res;
+  }
   res = InitializeBufferManagement(characteristics.get());
   if (res != OK) {
     ALOGE("%s: Initialize buffer management failed: %s(%d)", __FUNCTION__,
@@ -703,7 +714,8 @@
   // IsStreamCombinationSupported doesn't match the
   // CameraDevice::IsStreamCombination. We should look at unifying the two for a
   // potentially cleaner code-base.
-  if (!utils::IsStreamUseCaseSupported(stream_config, stream_use_cases_)) {
+  if (!utils::IsStreamUseCaseSupported(stream_config, camera_id_,
+                                       camera_id_to_stream_use_cases_)) {
     return BAD_VALUE;
   }
   device_session_hwl_->setConfigureStreamsV2(v2);
diff --git a/common/hal/google_camera_hal/camera_device_session.h b/common/hal/google_camera_hal/camera_device_session.h
index 84433a1..f7fdf3d 100644
--- a/common/hal/google_camera_hal/camera_device_session.h
+++ b/common/hal/google_camera_hal/camera_device_session.h
@@ -21,6 +21,7 @@
 #include <set>
 #include <shared_mutex>
 #include <vector>
+#include <map>
 
 #include "camera_buffer_allocator_hwl.h"
 #include "camera_device_session_hwl.h"
@@ -436,7 +437,7 @@
   std::set<uint32_t> ignore_shutters_;
 
   // Stream use cases supported by this camera device
-  std::set<int64_t> stream_use_cases_;
+  std::map<uint32_t, std::set<int64_t>> camera_id_to_stream_use_cases_;
 
   static constexpr int32_t kInvalidStreamId = -1;
 
diff --git a/common/hal/hwl_interface/camera_device_hwl.h b/common/hal/hwl_interface/camera_device_hwl.h
index 18efeb8..4cbc282 100644
--- a/common/hal/hwl_interface/camera_device_hwl.h
+++ b/common/hal/hwl_interface/camera_device_hwl.h
@@ -23,6 +23,7 @@
 #include "camera_device_session_hwl.h"
 #include "hal_camera_metadata.h"
 #include "hal_types.h"
+#include "physical_camera_info_hwl.h"
 #include "profiler.h"
 
 namespace android {
@@ -33,7 +34,7 @@
 // a single physical camera. It provides methods to query static information
 // about the associated camera devices. It does not hold any states of the
 // camera device.
-class CameraDeviceHwl {
+class CameraDeviceHwl : public PhysicalCameraInfoHwl {
  public:
   virtual ~CameraDeviceHwl() = default;
 
@@ -48,12 +49,6 @@
   virtual status_t GetCameraCharacteristics(
       std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
 
-  // Get the characteristics of the physical camera of this camera device.
-  // characteristics will be filled by CameraDeviceHwl.
-  virtual status_t GetPhysicalCameraCharacteristics(
-      uint32_t physical_camera_id,
-      std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
-
   // Set the torch mode of the camera device. The torch mode status remains
   // unchanged after this CameraDevice instance is destroyed.
   virtual status_t SetTorchMode(TorchMode mode) = 0;
diff --git a/common/hal/hwl_interface/camera_device_session_hwl.h b/common/hal/hwl_interface/camera_device_session_hwl.h
index 8e4f8d5..7984287 100644
--- a/common/hal/hwl_interface/camera_device_session_hwl.h
+++ b/common/hal/hwl_interface/camera_device_session_hwl.h
@@ -24,6 +24,7 @@
 #include "hal_camera_metadata.h"
 #include "hwl_types.h"
 #include "multicam_coordinator_hwl.h"
+#include "physical_camera_info_hwl.h"
 #include "profiler.h"
 #include "session_data_defs.h"
 #include "zoom_ratio_mapper_hwl.h"
@@ -33,7 +34,7 @@
 
 // CameraDeviceSessionHwl provides methods to return default settings,
 // create pipelines, submit capture requests, and flush the session.
-class CameraDeviceSessionHwl {
+class CameraDeviceSessionHwl : public PhysicalCameraInfoHwl {
  public:
   virtual ~CameraDeviceSessionHwl() = default;
 
@@ -132,11 +133,6 @@
   // Return the camera ID that this camera device session is associated with.
   virtual uint32_t GetCameraId() const = 0;
 
-  // Return the physical camera ID that this camera device session is associated
-  // with. If the camera device does not have multiple physical camera devices,
-  // this method should return an empty std::vector.
-  virtual std::vector<uint32_t> GetPhysicalCameraIds() const = 0;
-
   // Returns true if the two given physical camera ids can be streamed
   // simultaneously from this device session.
   virtual bool CanStreamSimultaneously(uint32_t /* physical_camera_id_1 */,
@@ -148,11 +144,6 @@
   virtual status_t GetCameraCharacteristics(
       std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
 
-  // Return the characteristics of a physical camera belonging to this device session.
-  virtual status_t GetPhysicalCameraCharacteristics(
-      uint32_t physical_camera_id,
-      std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
-
   // See common/session_data_def.h for more info on Session Data API
   // Set a key/value pair for this session
   virtual status_t SetSessionData(SessionDataKey key, void* value) = 0;
diff --git a/common/hal/hwl_interface/physical_camera_info_hwl.h b/common/hal/hwl_interface/physical_camera_info_hwl.h
new file mode 100644
index 0000000..ffd661e
--- /dev/null
+++ b/common/hal/hwl_interface/physical_camera_info_hwl.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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 HARDWARE_GOOGLE_CAMERA_HAL_HWL_INTERFACE_PHYSICAL_CAMERA_INFO_HWL_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_HWL_INTERFACE_PHYSICAL_CAMERA_INFO_HWL_H_
+
+#include <memory>
+#include <vector>
+
+#include "hal_camera_metadata.h"
+
+namespace android {
+namespace google_camera_hal {
+
+class PhysicalCameraInfoHwl {
+ public:
+  // Return the physical camera ID that this camera device is associated
+  // with. If the camera device does not have multiple physical camera devices,
+  // this method should return an empty std::vector.
+  virtual std::vector<uint32_t> GetPhysicalCameraIds() const {
+    return std::vector<uint32_t>();
+  };
+
+  // Get the characteristics of the physical camera of this camera device.
+  // characteristics will be filled by CameraDeviceHwl.
+  virtual status_t GetPhysicalCameraCharacteristics(
+      uint32_t physical_camera_id,
+      std::unique_ptr<HalCameraMetadata>* characteristics) const = 0;
+  virtual ~PhysicalCameraInfoHwl() = default;
+};
+
+}  // namespace google_camera_hal
+}  // namespace android
+
+#endif  // HARDWARE_GOOGLE_CAMERA_HAL_HWL_INTERFACE_PHYSICAL_CAMERA_INFO_HWL_H_
diff --git a/common/hal/utils/utils.cc b/common/hal/utils/utils.cc
index f2d8122..a9dd496 100644
--- a/common/hal/utils/utils.cc
+++ b/common/hal/utils/utils.cc
@@ -541,10 +541,55 @@
   return libs;
 }
 
-bool IsStreamUseCaseSupported(const StreamConfiguration& stream_config,
-                              const std::set<int64_t>& stream_use_cases,
-                              bool log_if_not_supported) {
+status_t GetPhysicalCameraStreamUseCases(
+    const PhysicalCameraInfoHwl* physical_camera_info,
+    std::map<uint32_t, std::set<int64_t>>* camera_id_to_stream_use_cases) {
+  status_t res = OK;
+  if (physical_camera_info == nullptr) {
+    ALOGE("physical_camera_info is nullptr");
+    return BAD_VALUE;
+  }
+  if (camera_id_to_stream_use_cases == nullptr) {
+    ALOGE("camera_id_to_stream_use_cases is nullptr");
+    return BAD_VALUE;
+  }
+  for (uint32_t physical_id : physical_camera_info->GetPhysicalCameraIds()) {
+    std::unique_ptr<google_camera_hal::HalCameraMetadata> physical_characteristics;
+    res = physical_camera_info->GetPhysicalCameraCharacteristics(
+        physical_id, &physical_characteristics);
+    if (res != OK) {
+      ALOGE("%s: Get physical camera characteristics failed: %s(%d)",
+            __FUNCTION__, strerror(-res), res);
+      return res;
+    }
+
+    res = utils::GetStreamUseCases(
+        physical_characteristics.get(),
+        &((*camera_id_to_stream_use_cases)[physical_id]));
+    if (res != OK) {
+      ALOGE("%s: Initializing stream use case failed: %s(%d)", __FUNCTION__,
+            strerror(-res), res);
+      return res;
+    }
+  }
+  return OK;
+}
+
+bool IsStreamUseCaseSupported(
+    const StreamConfiguration& stream_config, uint32_t logical_camera_id,
+    const std::map<uint32_t, std::set<int64_t>>& camera_id_to_stream_use_cases,
+    bool log_if_not_supported) {
   for (const auto& stream : stream_config.streams) {
+    uint32_t id = stream.is_physical_camera_stream ? stream.physical_camera_id
+                                                   : logical_camera_id;
+    auto it = camera_id_to_stream_use_cases.find(id);
+    if (it == camera_id_to_stream_use_cases.end()) {
+      if (log_if_not_supported) {
+        ALOGE("camera id %u not in set of supported physical camera ids", id);
+        return false;
+      }
+    }
+    const std::set<int64_t>& stream_use_cases = it->second;
     if (stream_use_cases.find(stream.use_case) == stream_use_cases.end()) {
       if (log_if_not_supported) {
         ALOGE("Stream use case %d not in set of supported use cases",
diff --git a/common/hal/utils/utils.h b/common/hal/utils/utils.h
index 16a60d2..1f73e7f 100644
--- a/common/hal/utils/utils.h
+++ b/common/hal/utils/utils.h
@@ -19,10 +19,12 @@
 
 #include <log/log.h>
 
+#include <map>
 #include <set>
 #include <utility>
 
 #include "hal_types.h"
+#include "physical_camera_info_hwl.h"
 
 namespace android {
 namespace google_camera_hal {
@@ -84,9 +86,14 @@
 status_t GetStreamUseCases(const HalCameraMetadata* static_metadata,
                            std::set<int64_t>* stream_use_cases);
 
-bool IsStreamUseCaseSupported(const StreamConfiguration& stream_config,
-                              const std::set<int64_t>& stream_use_cases,
-                              bool log_if_not_supported = true);
+status_t GetPhysicalCameraStreamUseCases(
+    const PhysicalCameraInfoHwl* physical_camera_info,
+    std::map<uint32_t, std::set<int64_t>>* camera_id_to_stream_use_cases);
+
+bool IsStreamUseCaseSupported(
+    const StreamConfiguration& stream_config, uint32_t logical_camera_id,
+    const std::map<uint32_t, std::set<int64_t>>& camera_id_to_stream_use_cases,
+    bool log_if_not_supported = true);
 
 // Map the rectangle to the coordination of HAL.
 void ConvertZoomRatio(float zoom_ratio, const Dimension& active_array_dimension,
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
index bbb0427..549eaff 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.cpp
@@ -133,6 +133,19 @@
   return OK;
 }
 
+std::vector<uint32_t> EmulatedCameraDeviceHwlImpl::GetPhysicalCameraIds() const {
+  std::vector<uint32_t> ret;
+  if (physical_device_map_.get() == nullptr ||
+      physical_device_map_->size() == 0) {
+    return ret;
+  }
+  ret.reserve(physical_device_map_->size());
+  for (const auto& entry : *physical_device_map_) {
+    ret.emplace_back(entry.first);
+  }
+  return ret;
+}
+
 status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics(
     uint32_t physical_camera_id,
     std::unique_ptr<HalCameraMetadata>* characteristics) const {
diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
index fa58400..e948f0b 100644
--- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
+++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceHWLImpl.h
@@ -20,6 +20,8 @@
 #include <camera_device_hwl.h>
 #include <hal_types.h>
 
+#include <vector>
+
 #include "EmulatedCameraDeviceInfo.h"
 #include "EmulatedSensor.h"
 #include "EmulatedTorchState.h"
@@ -55,6 +57,8 @@
   status_t GetCameraCharacteristics(
       std::unique_ptr<HalCameraMetadata>* characteristics) const override;
 
+  std::vector<uint32_t> GetPhysicalCameraIds() const override;
+
   status_t GetPhysicalCameraCharacteristics(
       uint32_t physical_camera_id,
       std::unique_ptr<HalCameraMetadata>* characteristics) const override;