Camera: Add ACTIVE_PHYSICAL_ID metadata for logical camera

And update VTS test for the new tag.

Test: Compile
Bug: 77915333
Change-Id: Ib0f1d54965047c5d20bf0c6f90ddb07225d8a328
diff --git a/camera/metadata/3.4/types.hal b/camera/metadata/3.4/types.hal
index 61a399e..28c56c8 100644
--- a/camera/metadata/3.4/types.hal
+++ b/camera/metadata/3.4/types.hal
@@ -75,6 +75,14 @@
 
     ANDROID_DEPTH_END_3_4,
 
+    /** android.logicalMultiCamera.activePhysicalId [dynamic, byte, public]
+     *
+     * <p>String containing the ID of the underlying active physical camera.</p>
+     */
+    ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_LOGICAL_MULTI_CAMERA_END_3_3,
+
+    ANDROID_LOGICAL_MULTI_CAMERA_END_3_4,
+
 };
 
 /*
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 60db5df..c3e1785 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -114,6 +114,8 @@
 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
 using ::android::hardware::camera::metadata::V3_4::CameraMetadataEnumAndroidSensorInfoColorFilterArrangement;
+using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag;
+using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata;
 using ::android::hardware::MessageQueue;
 using ::android::hardware::kSynchronizedReadWrite;
 using ::android::hidl::allocator::V1_0::IAllocator;
@@ -587,8 +589,8 @@
     };
 
     struct DeviceCb : public V3_5::ICameraDeviceCallback {
-        DeviceCb(CameraHidlTest *parent, bool checkMonochromeResult) : mParent(parent),
-                mCheckMonochromeResult(checkMonochromeResult) {}
+        DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
+                mParent(parent), mDeviceVersion(deviceVersion), mStaticMetadata(staticMeta) {}
 
         Return<void> processCaptureResult_3_4(
                 const hidl_vec<V3_4::CaptureResult>& results) override;
@@ -607,10 +609,12 @@
         void waitForBuffersReturned();
 
      private:
-        bool processCaptureResultLocked(const CaptureResult& results);
+        bool processCaptureResultLocked(const CaptureResult& results,
+                hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
 
         CameraHidlTest *mParent; // Parent object
-        bool mCheckMonochromeResult;
+        int mDeviceVersion;
+        const camera_metadata_t *mStaticMetadata;
         bool hasOutstandingBuffersLocked();
 
         /* members for requestStreamBuffers() and returnStreamBuffers()*/
@@ -755,6 +759,8 @@
     void verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
             const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
             bool expectedStatus);
+    void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
+            const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata);
 
     void verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,
             int deviceVerison, int32_t streamId, sp<DeviceCb> cb,
@@ -1008,7 +1014,7 @@
     bool notify = false;
     std::unique_lock<std::mutex> l(mParent->mLock);
     for (size_t i = 0 ; i < results.size(); i++) {
-        notify = processCaptureResultLocked(results[i].v3_2);
+        notify = processCaptureResultLocked(results[i].v3_2, results[i].physicalCameraMetadata);
     }
 
     l.unlock();
@@ -1027,8 +1033,9 @@
 
     bool notify = false;
     std::unique_lock<std::mutex> l(mParent->mLock);
+    ::android::hardware::hidl_vec<PhysicalCameraMetadata> noPhysMetadata;
     for (size_t i = 0 ; i < results.size(); i++) {
-        notify = processCaptureResultLocked(results[i]);
+        notify = processCaptureResultLocked(results[i], noPhysMetadata);
     }
 
     l.unlock();
@@ -1039,7 +1046,8 @@
     return Void();
 }
 
-bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results) {
+bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results,
+        hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata) {
     bool notify = false;
     uint32_t frameNumber = results.frameNumber;
 
@@ -1080,6 +1088,20 @@
             ADD_FAILURE();
             return notify;
         }
+
+        std::vector<::android::hardware::camera::device::V3_2::CameraMetadata> physResultMetadata;
+        physResultMetadata.resize(physicalCameraMetadata.size());
+        for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
+            physResultMetadata[i].resize(physicalCameraMetadata[i].fmqMetadataSize);
+            if (!request->resultQueue->read(physResultMetadata[i].data(),
+                    physicalCameraMetadata[i].fmqMetadataSize)) {
+                ALOGE("%s: Frame %d: Cannot read physical camera metadata from fmq,"
+                        "size = %" PRIu64, __func__, frameNumber,
+                        physicalCameraMetadata[i].fmqMetadataSize);
+                ADD_FAILURE();
+                return notify;
+            }
+        }
         resultSize = resultMetadata.size();
     } else if (results.result.size() > 0) {
         resultMetadata.setToExternal(const_cast<uint8_t *>(
@@ -1137,8 +1159,20 @@
         request->collectedResult.sort();
 
         // Verify final result metadata
-        if (mCheckMonochromeResult) {
-            mParent->verifyMonochromeCameraResult(request->collectedResult);
+        bool isAtLeast_3_5 = mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
+        if (isAtLeast_3_5) {
+            bool isMonochrome = Status::OK ==
+                    CameraHidlTest::isMonochromeCamera(mStaticMetadata);
+            if (isMonochrome) {
+                mParent->verifyMonochromeCameraResult(request->collectedResult);
+            }
+
+            // Verify logical camera result metadata
+            bool isLogicalCamera =
+                    Status::OK == CameraHidlTest::isLogicalMultiCamera(mStaticMetadata);
+            if (isLogicalCamera) {
+                mParent->verifyLogicalCameraResult(mStaticMetadata, request->collectedResult);
+            }
         }
     }
 
@@ -5056,7 +5090,7 @@
         ASSERT_EQ(Status::OK, s);
         staticMeta = clone_camera_metadata(
                 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
-         ASSERT_NE(nullptr, staticMeta);
+        ASSERT_NE(nullptr, staticMeta);
     });
     ASSERT_TRUE(ret.isOk());
 
@@ -5068,9 +5102,7 @@
         *supportsPartialResults = (*partialResultCount > 1);
     }
 
-    bool checkMonochromeResultTags = Status::OK == isMonochromeCamera(staticMeta) &&
-            deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
-    sp<DeviceCb> cb = new DeviceCb(this, checkMonochromeResultTags);
+    sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
     sp<ICameraDeviceSession> session;
     ret = device3_x->open(
         cb,
@@ -5208,9 +5240,7 @@
         *supportsPartialResults = (*partialResultCount > 1);
     }
 
-    bool checkMonochromeResultTags = Status::OK == isMonochromeCamera(staticMeta) &&
-            deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
-    sp<DeviceCb> cb = new DeviceCb(this, checkMonochromeResultTags);
+    sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
     ret = device3_x->open(
         cb,
         [&](auto status, const auto& newSession) {
@@ -5439,6 +5469,22 @@
         });
         ASSERT_TRUE(ret.isOk());
     }
+
+    // Make sure ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID is available in
+    // result keys.
+    if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
+        camera_metadata_ro_entry entry;
+        int retcode = find_camera_metadata_ro_entry(metadata,
+                ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
+        if ((0 == retcode) && (entry.count > 0)) {
+                ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
+                    static_cast<int32_t>(
+                            CameraMetadataTag::ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID)),
+                    entry.data.i32 + entry.count);
+        } else {
+            ADD_FAILURE() << "Get camera availableResultKeys failed!";
+        }
+    }
 }
 
 void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMetadata& chars) {
@@ -5647,6 +5693,24 @@
     cb->waitForBuffersReturned();
 }
 
+void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
+        const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) {
+    std::unordered_set<std::string> physicalIds;
+    Status rc = getPhysicalCameraIds(staticMetadata, &physicalIds);
+    ASSERT_TRUE(Status::OK == rc);
+    ASSERT_TRUE(physicalIds.size() > 1);
+
+    camera_metadata_ro_entry entry;
+    // Check mainPhysicalId
+    entry = resultMetadata.find(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+    if (entry.count > 0) {
+        std::string mainPhysicalId(reinterpret_cast<const char *>(entry.data.u8));
+        ASSERT_NE(physicalIds.find(mainPhysicalId), physicalIds.end());
+    } else {
+        ADD_FAILURE() << "Get LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID failed!";
+    }
+}
+
 // Open a device session with empty callbacks and return static metadata.
 void CameraHidlTest::openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider,
         sp<ICameraDeviceSession> *session /*out*/, camera_metadata_t **staticMeta /*out*/,