Merge changes from topic "libcamera2ndk_vendor_metadata" into qt-dev

* changes:
  libcamera2ndk_vendor: Add missing physicalCameraSettings metadata in saved cached CaptureRequest metadata.
  libcamera2ndk_vendor: Fix potential use after free of camera_metadata_t
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 1fdff40..529c167 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -259,15 +259,27 @@
     }
 }
 
+static void addMetadataToPhysicalCameraSettings(const CameraMetadata *metadata,
+        const std::string &cameraId, PhysicalCameraSettings *physicalCameraSettings) {
+    CameraMetadata metadataCopy = *metadata;
+    camera_metadata_t *camera_metadata = metadataCopy.release();
+    HCameraMetadata hCameraMetadata;
+    utils::convertToHidl(camera_metadata, &hCameraMetadata, /*shouldOwn*/ true);
+    physicalCameraSettings->settings.metadata(std::move(hCameraMetadata));
+    physicalCameraSettings->id = cameraId;
+}
+
 void CameraDevice::addRequestSettingsMetadata(ACaptureRequest *aCaptureRequest,
         sp<CaptureRequest> &req) {
-    CameraMetadata metadataCopy = aCaptureRequest->settings->getInternalData();
-    const camera_metadata_t *camera_metadata = metadataCopy.getAndLock();
-    HCameraMetadata hCameraMetadata;
-    utils::convertToHidl(camera_metadata, &hCameraMetadata);
-    metadataCopy.unlock(camera_metadata);
-    req->mPhysicalCameraSettings.resize(1);
-    req->mPhysicalCameraSettings[0].settings.metadata(std::move(hCameraMetadata));
+    req->mPhysicalCameraSettings.resize(1 + aCaptureRequest->physicalSettings.size());
+    addMetadataToPhysicalCameraSettings(&(aCaptureRequest->settings->getInternalData()), getId(),
+                    &(req->mPhysicalCameraSettings[0]));
+    size_t i = 1;
+    for (auto &physicalSetting : aCaptureRequest->physicalSettings) {
+        addMetadataToPhysicalCameraSettings(&(physicalSetting.second->getInternalData()),
+                physicalSetting.first, &(req->mPhysicalCameraSettings[i]));
+        i++;
+    }
 }
 
 camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
@@ -398,10 +410,9 @@
     cameraSettings.id = id;
     // TODO: Do we really need to copy the metadata here ?
     CameraMetadata metadataCopy = metadata->getInternalData();
-    const camera_metadata_t *cameraMetadata = metadataCopy.getAndLock();
+    camera_metadata_t *cameraMetadata = metadataCopy.release();
     HCameraMetadata hCameraMetadata;
-    utils::convertToHidl(cameraMetadata, &hCameraMetadata);
-    metadataCopy.unlock(cameraMetadata);
+    utils::convertToHidl(cameraMetadata, &hCameraMetadata, true);
     if (metadata != nullptr) {
         if (hCameraMetadata.data() != nullptr &&
             mCaptureRequestMetadataQueue != nullptr &&
@@ -426,11 +437,12 @@
         const std::string& id = req->mPhysicalCameraSettings[i].id;
         CameraMetadata clone;
         utils::convertFromHidlCloned(req->mPhysicalCameraSettings[i].settings.metadata(), &clone);
+        camera_metadata_t *clonep = clone.release();
         if (id == deviceId) {
-            pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
+            pRequest->settings = new ACameraMetadata(clonep, ACameraMetadata::ACM_REQUEST);
         } else {
             pRequest->physicalSettings[req->mPhysicalCameraSettings[i].id] =
-                    new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
+                    new ACameraMetadata(clonep, ACameraMetadata::ACM_REQUEST);
         }
     }
     pRequest->targets = new ACameraOutputTargets();
diff --git a/camera/ndk/ndk_vendor/impl/utils.cpp b/camera/ndk/ndk_vendor/impl/utils.cpp
index 5d2d47c..e4fb204 100644
--- a/camera/ndk/ndk_vendor/impl/utils.cpp
+++ b/camera/ndk/ndk_vendor/impl/utils.cpp
@@ -64,13 +64,14 @@
     return true;
 }
 
-// Note: existing data in dst will be gone. Caller still owns the memory of src
-void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst) {
+// Note: existing data in dst will be gone. dst owns memory if shouldOwn is set
+//       to true.
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn) {
     if (src == nullptr) {
         return;
     }
     size_t size = get_camera_metadata_size(src);
-    dst->setToExternal((uint8_t *) src, size);
+    dst->setToExternal((uint8_t *) src, size, shouldOwn);
     return;
 }
 
diff --git a/camera/ndk/ndk_vendor/impl/utils.h b/camera/ndk/ndk_vendor/impl/utils.h
index a03c7bc..f389f03 100644
--- a/camera/ndk/ndk_vendor/impl/utils.h
+++ b/camera/ndk/ndk_vendor/impl/utils.h
@@ -168,8 +168,8 @@
 
 bool convertFromHidlCloned(const HCameraMetadata &metadata, CameraMetadata *rawMetadata);
 
-// Note: existing data in dst will be gone. Caller still owns the memory of src
-void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst);
+// Note: existing data in dst will be gone.
+void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn = false);
 
 TemplateId convertToHidl(ACameraDevice_request_template templateId);