Introduce DynamicDisplayInfo

In this CL we introduce the getDynamicDisplayInfo call
on ISurfaceComposer which replaces the existing
 - getDisplayModes
 - getActiveDisplayMode
 - getColorModes
 - getActiveColorMode
 - getHdrCapabilities

This way all display properties can be queried atomically.

The current DisplayInfo class is moved to the androd::ui
namespace and it's renamed to StaticDisplayInfo.

ui::DisplayMode is now LightFlattenable and the mode ID is
int32_t instead of size_t in order to prevent serialization
problems.

Additionally we add the ID field to ui::DisplayMode. This
way we no longer need the supported display IDs to be
from 0 to N-1.

Bug: 159590486
Bug: 180539476
Test: presubmit, manually test that device boots
Change-Id: I52b170913ce47cb5df2e8417e6cc95d395df1fda
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7fada82..ecf5358 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -68,12 +68,13 @@
 #include <ui/ColorSpace.h>
 #include <ui/DebugUtils.h>
 #include <ui/DisplayId.h>
-#include <ui/DisplayInfo.h>
 #include <ui/DisplayMode.h>
 #include <ui/DisplayStatInfo.h>
 #include <ui/DisplayState.h>
+#include <ui/DynamicDisplayInfo.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
+#include <ui/StaticDisplayInfo.h>
 #include <utils/StopWatch.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
@@ -854,7 +855,8 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& displayToken, DisplayInfo* info) {
+status_t SurfaceFlinger::getStaticDisplayInfo(const sp<IBinder>& displayToken,
+                                              ui::StaticDisplayInfo* info) {
     if (!displayToken || !info) {
         return BAD_VALUE;
     }
@@ -875,7 +877,7 @@
     if (mEmulatedDisplayDensity) {
         info->density = mEmulatedDisplayDensity;
     } else {
-        info->density = info->connectionType == DisplayConnectionType::Internal
+        info->density = info->connectionType == ui::DisplayConnectionType::Internal
                 ? mInternalDisplayDensity
                 : FALLBACK_DENSITY;
     }
@@ -887,9 +889,9 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::getDisplayModes(const sp<IBinder>& displayToken,
-                                         Vector<ui::DisplayMode>* modes) {
-    if (!displayToken || !modes) {
+status_t SurfaceFlinger::getDynamicDisplayInfo(const sp<IBinder>& displayToken,
+                                               ui::DynamicDisplayInfo* info) {
+    if (!displayToken || !info) {
         return BAD_VALUE;
     }
 
@@ -900,16 +902,25 @@
         return NAME_NOT_FOUND;
     }
 
-    modes->clear();
+    info->activeDisplayModeId = static_cast<int32_t>(display->getActiveMode()->getId().value());
+    if (display->isPrimary()) {
+        if (const auto mode = getDesiredActiveMode()) {
+            info->activeDisplayModeId = static_cast<int32_t>(mode->modeId.value());
+        }
+    }
 
-    for (const auto& supportedMode : display->getSupportedModes()) {
-        ui::DisplayMode mode;
+    const auto& supportedModes = display->getSupportedModes();
+    info->supportedDisplayModes.clear();
+    info->supportedDisplayModes.reserve(supportedModes.size());
+    for (const auto& mode : supportedModes) {
+        ui::DisplayMode outMode;
+        outMode.id = static_cast<int32_t>(mode->getId().value());
 
-        auto width = supportedMode->getWidth();
-        auto height = supportedMode->getHeight();
+        auto width = mode->getWidth();
+        auto height = mode->getHeight();
 
-        auto xDpi = supportedMode->getDpiX();
-        auto yDpi = supportedMode->getDpiY();
+        auto xDpi = mode->getDpiX();
+        auto yDpi = mode->getDpiY();
 
         if (display->isPrimary() &&
             (internalDisplayOrientation == ui::ROTATION_90 ||
@@ -918,24 +929,24 @@
             std::swap(xDpi, yDpi);
         }
 
-        mode.resolution = ui::Size(width, height);
+        outMode.resolution = ui::Size(width, height);
 
         if (mEmulatedDisplayDensity) {
-            mode.xDpi = mEmulatedDisplayDensity;
-            mode.yDpi = mEmulatedDisplayDensity;
+            outMode.xDpi = mEmulatedDisplayDensity;
+            outMode.yDpi = mEmulatedDisplayDensity;
         } else {
-            mode.xDpi = xDpi;
-            mode.yDpi = yDpi;
+            outMode.xDpi = xDpi;
+            outMode.yDpi = yDpi;
         }
 
-        const nsecs_t period = supportedMode->getVsyncPeriod();
-        mode.refreshRate = Fps::fromPeriodNsecs(period).getValue();
+        const nsecs_t period = mode->getVsyncPeriod();
+        outMode.refreshRate = Fps::fromPeriodNsecs(period).getValue();
 
         const auto vsyncConfigSet =
-                mVsyncConfiguration->getConfigsForRefreshRate(Fps(mode.refreshRate));
-        mode.appVsyncOffset = vsyncConfigSet.late.appOffset;
-        mode.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
-        mode.group = supportedMode->getGroup();
+                mVsyncConfiguration->getConfigsForRefreshRate(Fps(outMode.refreshRate));
+        outMode.appVsyncOffset = vsyncConfigSet.late.appOffset;
+        outMode.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
+        outMode.group = mode->getGroup();
 
         // This is how far in advance a buffer must be queued for
         // presentation at a given time.  If you want a buffer to appear
@@ -949,11 +960,15 @@
         //
         // We add an additional 1ms to allow for processing time and
         // differences between the ideal and actual refresh rate.
-        mode.presentationDeadline = period - mode.sfVsyncOffset + 1000000;
+        outMode.presentationDeadline = period - outMode.sfVsyncOffset + 1000000;
 
-        modes->push_back(mode);
+        info->supportedDisplayModes.push_back(outMode);
     }
 
+    info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
+    info->supportedColorModes = getDisplayColorModes(display->getPhysicalId());
+
+    info->hdrCapabilities = display->getHdrCapabilities();
     return NO_ERROR;
 }
 
@@ -966,31 +981,6 @@
     return NO_ERROR;
 }
 
-int SurfaceFlinger::getActiveDisplayModeId(const sp<IBinder>& displayToken) {
-    int activeMode;
-    bool isPrimary;
-
-    {
-        Mutex::Autolock lock(mStateLock);
-
-        if (const auto display = getDisplayDeviceLocked(displayToken)) {
-            activeMode = display->getActiveMode()->getId().value();
-            isPrimary = display->isPrimary();
-        } else {
-            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
-            return NAME_NOT_FOUND;
-        }
-    }
-
-    if (isPrimary) {
-        if (const auto mode = getDesiredActiveMode()) {
-            return mode->modeId.value();
-        }
-    }
-
-    return activeMode;
-}
-
 void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
     ATRACE_CALL();
     auto refreshRate = mRefreshRateConfigs->getRefreshRateFromModeId(info.modeId);
@@ -1082,7 +1072,7 @@
 
     const auto upcomingMode = display->getMode(mUpcomingActiveMode.modeId);
     if (!upcomingMode) {
-        ALOGW("Upcoming active mode is no longer supported. Mode ID = %zu",
+        ALOGW("Upcoming active mode is no longer supported. Mode ID = %d",
               mUpcomingActiveMode.modeId.value());
         // TODO(b/159590486) Handle the error better. Some parts of SurfaceFlinger may
         // have been already updated with the upcoming active mode.
@@ -1142,13 +1132,13 @@
     const auto display = getDefaultDisplayDeviceLocked();
     const auto desiredMode = display->getMode(desiredActiveMode->modeId);
     if (!desiredMode) {
-        ALOGW("Desired display mode is no longer supported. Mode ID = %zu",
+        ALOGW("Desired display mode is no longer supported. Mode ID = %d",
               desiredActiveMode->modeId.value());
         clearDesiredActiveModeState();
         return;
     }
     const auto refreshRate = desiredMode->getFps();
-    ALOGV("%s changing active mode to %zu(%s)", __FUNCTION__, desiredMode->getId().value(),
+    ALOGV("%s changing active mode to %d(%s)", __FUNCTION__, desiredMode->getId().value(),
           to_string(refreshRate).c_str());
 
     if (!display || display->getActiveMode()->getId() == desiredActiveMode->modeId) {
@@ -1190,39 +1180,20 @@
     mSetActiveModePending = true;
 }
 
-status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken,
-                                              Vector<ColorMode>* outColorModes) {
-    if (!displayToken || !outColorModes) {
-        return BAD_VALUE;
-    }
-
-    std::vector<ColorMode> modes;
-    bool isInternalDisplay = false;
-    {
-        ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
-
-        const auto displayId = getPhysicalDisplayIdLocked(displayToken);
-        if (!displayId) {
-            return NAME_NOT_FOUND;
-        }
-
-        modes = getHwComposer().getColorModes(*displayId);
-        isInternalDisplay = displayId == getInternalDisplayIdLocked();
-    }
-    outColorModes->clear();
+std::vector<ColorMode> SurfaceFlinger::getDisplayColorModes(PhysicalDisplayId displayId) {
+    auto modes = getHwComposer().getColorModes(displayId);
+    bool isInternalDisplay = displayId == getInternalDisplayIdLocked();
 
     // If it's built-in display and the configuration claims it's not wide color capable,
     // filter out all wide color modes. The typical reason why this happens is that the
     // hardware is not good enough to support GPU composition of wide color, and thus the
     // OEMs choose to disable this capability.
     if (isInternalDisplay && !hasWideColorDisplay) {
-        std::remove_copy_if(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes),
-                            isWideColorMode);
-    } else {
-        std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
+        const auto newEnd = std::remove_if(modes.begin(), modes.end(), isWideColorMode);
+        modes.erase(newEnd, modes.end());
     }
 
-    return NO_ERROR;
+    return modes;
 }
 
 status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayToken,
@@ -1240,19 +1211,14 @@
     return NO_ERROR;
 }
 
-ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) {
-    Mutex::Autolock lock(mStateLock);
-
-    if (const auto display = getDisplayDeviceLocked(displayToken)) {
-        return display->getCompositionDisplay()->getState().colorMode;
-    }
-    return static_cast<ColorMode>(BAD_VALUE);
-}
-
 status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) {
     schedule([=]() MAIN_THREAD {
-        Vector<ColorMode> modes;
-        getDisplayColorModes(displayToken, &modes);
+        const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+        if (!displayId) {
+            ALOGE("Invalid display token %p", displayToken.get());
+            return;
+        }
+        const auto modes = getDisplayColorModes(*displayId);
         bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes);
         if (mode < ColorMode::NATIVE || !exists) {
             ALOGE("Attempt to set invalid active color mode %s (%d) for display token %p",
@@ -1349,28 +1315,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& displayToken,
-                                            HdrCapabilities* outCapabilities) const {
-    Mutex::Autolock lock(mStateLock);
-
-    const auto display = getDisplayDeviceLocked(displayToken);
-    if (!display) {
-        ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
-        return NAME_NOT_FOUND;
-    }
-
-    // At this point the DisplayDevice should already be set up,
-    // meaning the luminance information is already queried from
-    // hardware composer and stored properly.
-    const HdrCapabilities& capabilities = display->getHdrCapabilities();
-    *outCapabilities = HdrCapabilities(capabilities.getSupportedHdrTypes(),
-                                       capabilities.getDesiredMaxLuminance(),
-                                       capabilities.getDesiredMaxAverageLuminance(),
-                                       capabilities.getDesiredMinLuminance());
-
-    return NO_ERROR;
-}
-
 status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
                                                                ui::PixelFormat* outFormat,
                                                                ui::Dataspace* outDataspace,
@@ -1640,7 +1584,7 @@
 
     // Don't do any updating if the current fps is the same as the new one.
     if (!isDisplayModeAllowed(refreshRate.getModeId())) {
-        ALOGV("Skipping mode %zu as it is not part of allowed modes",
+        ALOGV("Skipping mode %d as it is not part of allowed modes",
               refreshRate.getModeId().value());
         return;
     }
@@ -2360,7 +2304,7 @@
 DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId displayId) const {
     const auto hwcModes = getHwComposer().getModes(displayId);
     DisplayModes modes;
-    size_t nextModeId = 0;
+    int32_t nextModeId = 0;
     for (const auto& hwcMode : hwcModes) {
         modes.push_back(DisplayMode::Builder(hwcMode.hwcId)
                                 .setId(DisplayModeId{nextModeId++})
@@ -5013,7 +4957,8 @@
         case GET_PHYSICAL_DISPLAY_TOKEN:
         case GET_DISPLAY_COLOR_MODES:
         case GET_DISPLAY_NATIVE_PRIMARIES:
-        case GET_DISPLAY_INFO:
+        case GET_STATIC_DISPLAY_INFO:
+        case GET_DYNAMIC_DISPLAY_INFO:
         case GET_DISPLAY_MODES:
         case GET_DISPLAY_STATE:
         case GET_DISPLAY_STATS:
@@ -6141,27 +6086,25 @@
             ? mRefreshRateConfigs->getRefreshRateFromModeId(*modeId)
             // NOTE: Choose the default mode ID, if Scheduler doesn't have one in mind.
             : mRefreshRateConfigs->getRefreshRateFromModeId(currentPolicy.defaultMode);
-    ALOGV("trying to switch to Scheduler preferred mode %zu (%s)",
+    ALOGV("trying to switch to Scheduler preferred mode %d (%s)",
           preferredRefreshRate.getModeId().value(), preferredRefreshRate.getName().c_str());
 
     if (isDisplayModeAllowed(preferredRefreshRate.getModeId())) {
-        ALOGV("switching to Scheduler preferred display mode %zu",
+        ALOGV("switching to Scheduler preferred display mode %d",
               preferredRefreshRate.getModeId().value());
         setDesiredActiveMode({preferredRefreshRate.getModeId(), Scheduler::ModeEvent::Changed});
     } else {
-        LOG_ALWAYS_FATAL("Desired display mode not allowed: %zu",
+        LOG_ALWAYS_FATAL("Desired display mode not allowed: %d",
                          preferredRefreshRate.getModeId().value());
     }
 
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
-                                                    size_t defaultMode, bool allowGroupSwitching,
-                                                    float primaryRefreshRateMin,
-                                                    float primaryRefreshRateMax,
-                                                    float appRequestRefreshRateMin,
-                                                    float appRequestRefreshRateMax) {
+status_t SurfaceFlinger::setDesiredDisplayModeSpecs(
+        const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode, bool allowGroupSwitching,
+        float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin,
+        float appRequestRefreshRateMax) {
     ATRACE_CALL();
 
     if (!displayToken) {
@@ -6192,10 +6135,13 @@
     return future.get();
 }
 
-status_t SurfaceFlinger::getDesiredDisplayModeSpecs(
-        const sp<IBinder>& displayToken, size_t* outDefaultMode, bool* outAllowGroupSwitching,
-        float* outPrimaryRefreshRateMin, float* outPrimaryRefreshRateMax,
-        float* outAppRequestRefreshRateMin, float* outAppRequestRefreshRateMax) {
+status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
+                                                    ui::DisplayModeId* outDefaultMode,
+                                                    bool* outAllowGroupSwitching,
+                                                    float* outPrimaryRefreshRateMin,
+                                                    float* outPrimaryRefreshRateMax,
+                                                    float* outAppRequestRefreshRateMin,
+                                                    float* outAppRequestRefreshRateMax) {
     ATRACE_CALL();
 
     if (!displayToken || !outDefaultMode || !outPrimaryRefreshRateMin ||