Camera: Support physical camera metadata in capture result

- Add physical camera metadata in capture result.
- Adjust capture_result book-keeping for physical capture result.
- Adapt to new version of ICameraDeviceCallback.
- Batch physical metadata with logical metadata within one
process_capture_result call.

Test: testLogicalCameraTest CTS test
Bug: 64691172
Change-Id: I63fd343770cbb6183b7c6e4566c698f69801a8e8
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index e6c0d00..928a6bc 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -60,6 +60,39 @@
     return OK;
 }
 
+status_t PhysicalCaptureResultInfo::readFromParcel(const android::Parcel* parcel) {
+    status_t res;
+
+    mPhysicalCameraId.remove(mPhysicalCameraId.size());
+    mPhysicalCameraMetadata.clear();
+
+    if ((res = parcel->readString16(&mPhysicalCameraId)) != OK) {
+        ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+        return res;
+    }
+
+    if ((res = mPhysicalCameraMetadata.readFromParcel(parcel)) != OK) {
+        ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
+        return res;
+    }
+    return OK;
+}
+
+status_t PhysicalCaptureResultInfo::writeToParcel(android::Parcel* parcel) const {
+    status_t res;
+    if ((res = parcel->writeString16(mPhysicalCameraId)) != OK) {
+        ALOGE("%s: Failed to write physical camera ID to parcel: %d",
+                __FUNCTION__, res);
+        return res;
+    }
+    if ((res = mPhysicalCameraMetadata.writeToParcel(parcel)) != OK) {
+        ALOGE("%s: Failed to write physical camera metadata to parcel: %d",
+                __FUNCTION__, res);
+        return res;
+    }
+    return OK;
+}
+
 CaptureResult::CaptureResult() :
         mMetadata(), mResultExtras() {
 }
@@ -67,6 +100,7 @@
 CaptureResult::CaptureResult(const CaptureResult &otherResult) {
     mResultExtras = otherResult.mResultExtras;
     mMetadata = otherResult.mMetadata;
+    mPhysicalMetadatas = otherResult.mPhysicalMetadatas;
 }
 
 status_t CaptureResult::readFromParcel(android::Parcel *parcel) {
@@ -79,6 +113,7 @@
     }
 
     mMetadata.clear();
+    mPhysicalMetadatas.clear();
 
     status_t res = OK;
     res = mMetadata.readFromParcel(parcel);
@@ -89,6 +124,34 @@
     }
     ALOGV("%s: Read metadata from parcel", __FUNCTION__);
 
+    int32_t physicalMetadataCount;
+    if ((res = parcel->readInt32(&physicalMetadataCount)) != OK) {
+        ALOGE("%s: Failed to read the physical metadata count from parcel: %d", __FUNCTION__, res);
+        return res;
+    }
+    if (physicalMetadataCount < 0) {
+        ALOGE("%s: Invalid physical metadata count from parcel: %d",
+                __FUNCTION__, physicalMetadataCount);
+        return BAD_VALUE;
+    }
+
+    for (int32_t i = 0; i < physicalMetadataCount; i++) {
+        String16 cameraId;
+        if ((res = parcel->readString16(&cameraId)) != OK) {
+            ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+            return res;
+        }
+
+        CameraMetadata physicalMetadata;
+        if ((res = physicalMetadata.readFromParcel(parcel)) != OK) {
+            ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
+            return res;
+        }
+
+        mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), cameraId, physicalMetadata);
+    }
+    ALOGV("%s: Read physical metadata from parcel", __FUNCTION__);
+
     res = mResultExtras.readFromParcel(parcel);
     if (res != OK) {
         ALOGE("%s: Failed to read result extras from parcel.",
@@ -118,6 +181,27 @@
     }
     ALOGV("%s: Wrote metadata to parcel", __FUNCTION__);
 
+    int32_t physicalMetadataCount = static_cast<int32_t>(mPhysicalMetadatas.size());
+    res = parcel->writeInt32(physicalMetadataCount);
+    if (res != OK) {
+        ALOGE("%s: Failed to write physical metadata count to parcel: %d",
+                __FUNCTION__, res);
+        return BAD_VALUE;
+    }
+    for (const auto& physicalMetadata : mPhysicalMetadatas) {
+        if ((res = parcel->writeString16(physicalMetadata.mPhysicalCameraId)) != OK) {
+            ALOGE("%s: Failed to write physical camera ID to parcel: %d",
+                    __FUNCTION__, res);
+            return res;
+        }
+        if ((res = physicalMetadata.mPhysicalCameraMetadata.writeToParcel(parcel)) != OK) {
+            ALOGE("%s: Failed to write physical camera metadata to parcel: %d",
+                    __FUNCTION__, res);
+            return res;
+        }
+    }
+    ALOGV("%s: Wrote physical camera metadata to parcel", __FUNCTION__);
+
     res = mResultExtras.writeToParcel(parcel);
     if (res != OK) {
         ALOGE("%s: Failed to write result extras to parcel", __FUNCTION__);
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index 4db7f85..58b19a3 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.CaptureResultExtras;
+import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
 
 /** @hide */
 interface ICameraDeviceCallbacks
@@ -36,7 +37,8 @@
     oneway void onDeviceIdle();
     oneway void onCaptureStarted(in CaptureResultExtras resultExtras, long timestamp);
     oneway void onResultReceived(in CameraMetadataNative result,
-                                 in CaptureResultExtras resultExtras);
+                                 in CaptureResultExtras resultExtras,
+                                 in PhysicalCaptureResultInfo[] physicalCaptureResultInfos);
     oneway void onPrepared(int streamId);
 
     /**
diff --git a/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl b/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl
new file mode 100644
index 0000000..78d9b7b
--- /dev/null
+++ b/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.camera2.impl;
+
+/** @hide */
+parcelable PhysicalCaptureResultInfo cpp_header "camera/CaptureResult.h";
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index 917d953..56fa178 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -91,14 +91,36 @@
     virtual status_t                readFromParcel(const android::Parcel* parcel) override;
     virtual status_t                writeToParcel(android::Parcel* parcel) const override;
 };
+
+struct PhysicalCaptureResultInfo : public android::Parcelable {
+
+    PhysicalCaptureResultInfo()
+        : mPhysicalCameraId(),
+          mPhysicalCameraMetadata() {
+    }
+    PhysicalCaptureResultInfo(const String16& cameraId,
+            const CameraMetadata& cameraMetadata)
+            : mPhysicalCameraId(cameraId),
+              mPhysicalCameraMetadata(cameraMetadata) {
+    }
+
+    String16  mPhysicalCameraId;
+    CameraMetadata mPhysicalCameraMetadata;
+
+    virtual status_t                readFromParcel(const android::Parcel* parcel) override;
+    virtual status_t                writeToParcel(android::Parcel* parcel) const override;
+};
+
 } // namespace impl
 } // namespace camera2
 } // namespace hardware
 
 using hardware::camera2::impl::CaptureResultExtras;
+using hardware::camera2::impl::PhysicalCaptureResultInfo;
 
 struct CaptureResult : public virtual LightRefBase<CaptureResult> {
     CameraMetadata          mMetadata;
+    std::vector<PhysicalCaptureResultInfo> mPhysicalMetadatas;
     CaptureResultExtras     mResultExtras;
 
     CaptureResult();
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index ef1c61f..907debc 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1406,7 +1406,9 @@
 binder::Status
 CameraDevice::ServiceCallback::onResultReceived(
         const CameraMetadata& metadata,
-        const CaptureResultExtras& resultExtras) {
+        const CaptureResultExtras& resultExtras,
+        const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
+    (void) physicalResultInfos;
     binder::Status ret = binder::Status::ok();
 
     sp<CameraDevice> dev = mDevice.promote();
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 1db3dfb..1369148 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -74,7 +74,8 @@
         binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
                               int64_t timestamp) override;
         binder::Status onResultReceived(const CameraMetadata& metadata,
-                              const CaptureResultExtras& resultExtras) override;
+                              const CaptureResultExtras& resultExtras,
+                              const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) override;
         binder::Status onPrepared(int streamId) override;
         binder::Status onRequestQueueEmpty() override;
         binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 24c0c51..1de7013 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -198,9 +198,11 @@
 
 
     virtual binder::Status onResultReceived(const CameraMetadata& metadata,
-            const CaptureResultExtras& resultExtras) {
+            const CaptureResultExtras& resultExtras,
+            const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
         (void) metadata;
         (void) resultExtras;
+        (void) physicalResultInfos;
         Mutex::Autolock l(mLock);
         mLastStatus = SENT_RESULT;
         mStatusesHit.push_back(mLastStatus);