CameraITS: Add physical camera metadata support

- Serialize physical camera metadata for logical multi-camera if physical
camera is requested.
- Update CTS test to use getPhysicalResultMetadata call
- Remove redundant request and static metadata from captureResults.

Test: Run hacked test_yuv_plus_raw to stream physical streams
Bug: 66697407
Change-Id: I8fdfd9992fc988de59f84a84f3cb99383abf1a01
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 3e3cc02..7a20877 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -756,6 +756,7 @@
                 "rawStats":[], "dng":[], "jpeg":[]}
         yuv_bufs = {size:[] for size in yuv_sizes}
         mds = []
+        physical_mds = []
         widths = None
         heights = None
         while nbufs < ncap*nsurf or len(mds) < ncap:
@@ -772,6 +773,7 @@
                 nbufs += 1
             elif jsonObj['tag'] == 'captureResults':
                 mds.append(jsonObj['objValue']['captureResult'])
+                physical_mds.append(jsonObj['objValue']['physicalResults'])
                 outputs = jsonObj['objValue']['outputs']
                 widths = [out['width'] for out in outputs]
                 heights = [out['height'] for out in outputs]
@@ -791,7 +793,13 @@
                 obj["width"] = widths[j]
                 obj["height"] = heights[j]
                 obj["format"] = fmt
-                obj["metadata"] = mds[i]
+                if j in physical_cam_ids:
+                    for physical_md in physical_mds[i]:
+                        if physical_cam_ids[j] in physical_md:
+                            obj["metadata"] = physical_md[physical_cam_ids[j]]
+                            break
+                else:
+                    obj["metadata"] = mds[i]
 
                 if j in physical_cam_ids:
                     obj["data"] = physical_buffers[physical_cam_ids[j]][i]
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 8677941..6b8e9b2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -86,8 +86,10 @@
 import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingDeque;
@@ -211,6 +213,9 @@
     private HandlerThread mSensorThread = null;
     private Handler mSensorHandler = null;
 
+    private static final int SERIALIZER_SURFACES_ID = 2;
+    private static final int SERIALIZER_PHYSICAL_METADATA_ID = 3;
+
     public interface CaptureCallback {
         void onCaptureAvailable(Image capture, String physicalCameraId);
     }
@@ -420,9 +425,20 @@
                             jsonObj.put("captureResult", ItsSerializer.serialize(
                                     (CaptureResult)obj));
                         } else if (obj instanceof JSONArray) {
-                            jsonObj.put("outputs", (JSONArray)obj);
+                            if (tag == "captureResults") {
+                                if (i == SERIALIZER_SURFACES_ID) {
+                                    jsonObj.put("outputs", (JSONArray)obj);
+                                } else if (i == SERIALIZER_PHYSICAL_METADATA_ID) {
+                                    jsonObj.put("physicalResults", (JSONArray)obj);
+                                } else {
+                                    throw new ItsException(
+                                            "Unsupported JSONArray for captureResults");
+                                }
+                            } else {
+                                jsonObj.put("outputs", (JSONArray)obj);
+                            }
                         } else {
-                            throw new ItsException("Invalid object received for serialiation");
+                            throw new ItsException("Invalid object received for serialization");
                         }
                     }
                     if (tag == null) {
@@ -750,7 +766,7 @@
 
         public void sendResponseCaptureResult(CameraCharacteristics props,
                                               CaptureRequest request,
-                                              CaptureResult result,
+                                              TotalCaptureResult result,
                                               ImageReader[] readers)
                 throws ItsException {
             try {
@@ -788,12 +804,19 @@
                     jsonSurfaces.put(jsonSurface);
                 }
 
-                Object objs[] = new Object[5];
+                Map<String, CaptureResult> physicalMetadata =
+                        result.getPhysicalCameraResults();
+                JSONArray jsonPhysicalMetadata = new JSONArray();
+                for (Map.Entry<String, CaptureResult> pair : physicalMetadata.entrySet()) {
+                    JSONObject jsonOneMetadata = new JSONObject();
+                    jsonOneMetadata.put(pair.getKey(), ItsSerializer.serialize(pair.getValue()));
+                    jsonPhysicalMetadata.put(jsonOneMetadata);
+                }
+                Object objs[] = new Object[4];
                 objs[0] = "captureResults";
-                objs[1] = props;
-                objs[2] = request;
-                objs[3] = result;
-                objs[4] = jsonSurfaces;
+                objs[1] = result;
+                objs[SERIALIZER_SURFACES_ID] = jsonSurfaces;
+                objs[SERIALIZER_PHYSICAL_METADATA_ID] = jsonPhysicalMetadata;
                 mSerializerQueue.put(objs);
             } catch (org.json.JSONException e) {
                 throw new ItsException("JSON error: ", e);