Convert DynamicDisplayInfo to AIDL parcelable

And migrate related ISurfaceComposer::getDynamicDisplayInfo() method to AIDL.
(1) add android::gui::DynamicDisplayInfo etc. for serialization
(2) remove serialization code from the orignal DynamicDisplayInfo and
DisplayMode and HdrCapabilities classes
(3) convert between ui::DynamicDisplayInfo and gui::DynamicDisplayInfo

Bug: 220074970
Test: manual
Change-Id: If3c81c5fd006c281f6d38766bf415a971b0a1925
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index c5de09a..a9473d4 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -225,17 +225,6 @@
         return result;
     }
 
-    status_t getDynamicDisplayInfo(const sp<IBinder>& display,
-                                   ui::DynamicDisplayInfo* info) override {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeStrongBinder(display);
-        remote()->transact(BnSurfaceComposer::GET_DYNAMIC_DISPLAY_INFO, data, &reply);
-        const status_t result = reply.readInt32();
-        if (result != NO_ERROR) return result;
-        return reply.read(*info);
-    }
-
     status_t getDisplayNativePrimaries(const sp<IBinder>& display,
                                        ui::DisplayPrimaries& primaries) override {
         Parcel data, reply;
@@ -1133,16 +1122,6 @@
             reply->writeStrongBinder(IInterface::asBinder(connection));
             return NO_ERROR;
         }
-        case GET_DYNAMIC_DISPLAY_INFO: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            ui::DynamicDisplayInfo info;
-            const sp<IBinder> display = data.readStrongBinder();
-            const status_t result = getDynamicDisplayInfo(display, &info);
-            SAFE_PARCEL(reply->writeInt32, result);
-            if (result != NO_ERROR) return result;
-            SAFE_PARCEL(reply->write, info);
-            return NO_ERROR;
-        }
         case GET_DISPLAY_NATIVE_PRIMARIES: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             ui::DisplayPrimaries primaries;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 0f0a5c8..bee820d 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -366,12 +366,13 @@
         return NAME_NOT_FOUND;
     }
 
-    ui::DynamicDisplayInfo info;
-    if (status_t err = composerService()->getDynamicDisplayInfo(display, &info); err != NO_ERROR) {
-        return err;
+    gui::DynamicDisplayInfo info;
+    if (binder::Status status = composerServiceAIDL()->getDynamicDisplayInfo(display, &info);
+        !status.isOk()) {
+        return status.transactionError();
     }
 
-    *supported = !info.hdrCapabilities.getSupportedHdrTypes().empty();
+    *supported = !info.hdrCapabilities.supportedHdrTypes.empty();
     return NO_ERROR;
 }
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index b4979d9..6702fef 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2187,8 +2187,53 @@
 }
 
 status_t SurfaceComposerClient::getDynamicDisplayInfo(const sp<IBinder>& display,
-                                                      ui::DynamicDisplayInfo* info) {
-    return ComposerService::getComposerService()->getDynamicDisplayInfo(display, info);
+                                                      ui::DynamicDisplayInfo* outInfo) {
+    gui::DynamicDisplayInfo ginfo;
+    binder::Status status =
+            ComposerServiceAIDL::getComposerService()->getDynamicDisplayInfo(display, &ginfo);
+    if (status.isOk()) {
+        // convert gui::DynamicDisplayInfo to ui::DynamicDisplayInfo
+        outInfo->supportedDisplayModes.clear();
+        outInfo->supportedDisplayModes.reserve(ginfo.supportedDisplayModes.size());
+        for (const auto& mode : ginfo.supportedDisplayModes) {
+            ui::DisplayMode outMode;
+            outMode.id = mode.id;
+            outMode.resolution.width = mode.resolution.width;
+            outMode.resolution.height = mode.resolution.height;
+            outMode.xDpi = mode.xDpi;
+            outMode.yDpi = mode.yDpi;
+            outMode.refreshRate = mode.refreshRate;
+            outMode.appVsyncOffset = mode.appVsyncOffset;
+            outMode.sfVsyncOffset = mode.sfVsyncOffset;
+            outMode.presentationDeadline = mode.presentationDeadline;
+            outMode.group = mode.group;
+            outInfo->supportedDisplayModes.push_back(outMode);
+        }
+
+        outInfo->activeDisplayModeId = ginfo.activeDisplayModeId;
+
+        outInfo->supportedColorModes.clear();
+        outInfo->supportedColorModes.reserve(ginfo.supportedColorModes.size());
+        for (const auto& cmode : ginfo.supportedColorModes) {
+            outInfo->supportedColorModes.push_back(static_cast<ui::ColorMode>(cmode));
+        }
+
+        outInfo->activeColorMode = static_cast<ui::ColorMode>(ginfo.activeColorMode);
+
+        std::vector<ui::Hdr> types;
+        types.reserve(ginfo.hdrCapabilities.supportedHdrTypes.size());
+        for (const auto& hdr : ginfo.hdrCapabilities.supportedHdrTypes) {
+            types.push_back(static_cast<ui::Hdr>(hdr));
+        }
+        outInfo->hdrCapabilities = HdrCapabilities(types, ginfo.hdrCapabilities.maxLuminance,
+                                                   ginfo.hdrCapabilities.maxAverageLuminance,
+                                                   ginfo.hdrCapabilities.minLuminance);
+
+        outInfo->autoLowLatencyModeSupported = ginfo.autoLowLatencyModeSupported;
+        outInfo->gameContentTypeSupported = ginfo.gameContentTypeSupported;
+        outInfo->preferredBootDisplayMode = ginfo.preferredBootDisplayMode;
+    }
+    return status.transactionError();
 }
 
 status_t SurfaceComposerClient::getActiveDisplayMode(const sp<IBinder>& display,
diff --git a/libs/gui/aidl/android/gui/DisplayModelId.aidl b/libs/gui/aidl/android/gui/DisplayMode.aidl
similarity index 65%
copy from libs/gui/aidl/android/gui/DisplayModelId.aidl
copy to libs/gui/aidl/android/gui/DisplayMode.aidl
index d75777b..3cd77f8 100644
--- a/libs/gui/aidl/android/gui/DisplayModelId.aidl
+++ b/libs/gui/aidl/android/gui/DisplayMode.aidl
@@ -16,11 +16,21 @@
 
 package android.gui;
 
-// Product-specific information about the display or the directly connected device on the
-// display chain. For example, if the display is transitively connected, this field may contain
-// product information about the intermediate device.
+import android.gui.Size;
+
+// Mode supported by physical display.
+// Make sure to sync with libui DisplayMode.h
 
 /** @hide */
-parcelable DisplayModelId {
+parcelable DisplayMode {
     int id;
+    Size resolution;
+    float xDpi = 0.0f;
+    float yDpi = 0.0f;
+
+    float refreshRate = 0.0f;
+    long appVsyncOffset = 0;
+    long sfVsyncOffset = 0;
+    long presentationDeadline = 0;
+    int group = -1;
 }
diff --git a/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl b/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl
new file mode 100644
index 0000000..57e6081
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 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.gui;
+
+import android.gui.DisplayMode;
+import android.gui.HdrCapabilities;
+
+// Information about a physical display which may change on hotplug reconnect.
+// Make sure to sync with libui DynamicDisplayInfo.h
+
+/** @hide */
+parcelable DynamicDisplayInfo {
+    List<DisplayMode> supportedDisplayModes;
+
+    int activeDisplayModeId;
+
+    int[] supportedColorModes;
+    int activeColorMode;
+    HdrCapabilities hdrCapabilities;
+
+    // True if the display reports support for HDMI 2.1 Auto Low Latency Mode.
+    // For more information, see the HDMI 2.1 specification.
+    boolean autoLowLatencyModeSupported;
+
+    // True if the display reports support for Game Content Type.
+    // For more information, see the HDMI 1.4 specification.
+    boolean gameContentTypeSupported;
+
+    // The boot display mode preferred by the implementation.
+    int preferredBootDisplayMode;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayModelId.aidl b/libs/gui/aidl/android/gui/HdrCapabilities.aidl
similarity index 69%
rename from libs/gui/aidl/android/gui/DisplayModelId.aidl
rename to libs/gui/aidl/android/gui/HdrCapabilities.aidl
index d75777b..9d06da9 100644
--- a/libs/gui/aidl/android/gui/DisplayModelId.aidl
+++ b/libs/gui/aidl/android/gui/HdrCapabilities.aidl
@@ -16,11 +16,12 @@
 
 package android.gui;
 
-// Product-specific information about the display or the directly connected device on the
-// display chain. For example, if the display is transitively connected, this field may contain
-// product information about the intermediate device.
+// Make sure to sync with libui HdrCapabilities.h
 
 /** @hide */
-parcelable DisplayModelId {
-    int id;
+parcelable HdrCapabilities {
+    int[] supportedHdrTypes;
+    float maxLuminance;
+    float maxAverageLuminance;
+    float minLuminance;
 }
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index f6cd5ec..175007d 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -21,6 +21,7 @@
 import android.gui.DisplayState;
 import android.gui.DisplayStatInfo;
 import android.gui.StaticDisplayInfo;
+import android.gui.DynamicDisplayInfo;
 import android.gui.IHdrLayerInfoListener;
 import android.gui.LayerCaptureArgs;
 import android.gui.IScreenCaptureListener;
@@ -70,6 +71,11 @@
     StaticDisplayInfo getStaticDisplayInfo(IBinder display);
 
     /**
+     * Gets dynamic information about given physical display.
+     */
+    DynamicDisplayInfo getDynamicDisplayInfo(IBinder display);
+
+    /**
      * Clears the user-preferred display mode. The device should now boot in system preferred
      * display mode.
      */
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 29e38b8..ed8254a 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -160,11 +160,6 @@
     virtual status_t getSupportedFrameTimestamps(
             std::vector<FrameEvent>* outSupported) const = 0;
 
-    /**
-     * Gets dynamic information about given physical display.
-     */
-    virtual status_t getDynamicDisplayInfo(const sp<IBinder>& display, ui::DynamicDisplayInfo*) = 0;
-
     virtual status_t getDisplayNativePrimaries(const sp<IBinder>& display,
             ui::DisplayPrimaries& primaries) = 0;
     virtual status_t setActiveColorMode(const sp<IBinder>& display,
@@ -490,7 +485,7 @@
         ADD_TRANSACTION_TRACE_LISTENER,
         GET_GPU_CONTEXT_PRIORITY,
         GET_MAX_ACQUIRED_BUFFER_COUNT,
-        GET_DYNAMIC_DISPLAY_INFO,
+        GET_DYNAMIC_DISPLAY_INFO, // Deprecated. Autogenerated by .aidl now.
         ADD_FPS_LISTENER,
         REMOVE_FPS_LISTENER,
         OVERRIDE_HDR_TYPES,
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index e02299d..bf1b43d 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -733,10 +733,6 @@
         return NO_ERROR;
     }
 
-    status_t getDynamicDisplayInfo(const sp<IBinder>& /*display*/,
-                                   ui::DynamicDisplayInfo*) override {
-        return NO_ERROR;
-    }
     status_t getDisplayNativePrimaries(const sp<IBinder>& /*display*/,
             ui::DisplayPrimaries& /*primaries*/) override {
         return NO_ERROR;
@@ -931,6 +927,11 @@
         return binder::Status::ok();
     }
 
+    binder::Status getDynamicDisplayInfo(const sp<IBinder>& /*display*/,
+                                         gui::DynamicDisplayInfo* /*outInfo*/) override {
+        return binder::Status::ok();
+    }
+
     binder::Status clearBootDisplayMode(const sp<IBinder>& /*display*/) override {
         return binder::Status::ok();
     }