Map the hwc-id -> SF-id in getPreferredBootDisplayMode and SF-Id -> HWC
id in setUserPreferredDisplayMode

Bug: 219959797
Test: m
Change-Id: I20e69dd50ad06b527a833ebef5e617b2ebd3d236
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 47aacc9..6a3fcb7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -57,7 +57,7 @@
     virtual void createClientCompositionCache(uint32_t cacheSize) = 0;
 
     // Returns the boot display mode preferred by HWC.
-    virtual int32_t getPreferredBootModeId() const = 0;
+    virtual int32_t getPreferredBootHwcConfigId() const = 0;
 
 protected:
     ~Display() = default;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index ebe112b..6c7ba22 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -62,7 +62,7 @@
     bool isSecure() const override;
     bool isVirtual() const override;
     void disconnect() override;
-    int32_t getPreferredBootModeId() const override;
+    int32_t getPreferredBootHwcConfigId() const override;
     void createDisplayColorProfile(
             const compositionengine::DisplayColorProfileCreationArgs&) override;
     void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
@@ -88,7 +88,7 @@
     DisplayId mId;
     bool mIsDisconnected = false;
     Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
-    int32_t mPreferredBootDisplayModeId = -1;
+    int32_t mPreferredBootHwcConfigId = -1;
 };
 
 // This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 84afb59..d90cc90 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -34,7 +34,7 @@
     MOCK_CONST_METHOD0(getId, DisplayId());
     MOCK_CONST_METHOD0(isSecure, bool());
     MOCK_CONST_METHOD0(isVirtual, bool());
-    MOCK_CONST_METHOD0(getPreferredBootModeId, int32_t());
+    MOCK_CONST_METHOD0(getPreferredBootHwcConfigId, int32_t());
 
     MOCK_METHOD0(disconnect, void());
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index a3188f3..b9d7983 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -66,7 +66,7 @@
     std::optional<hal::HWConfigId> preferredBootModeId =
             getCompositionEngine().getHwComposer().getPreferredBootDisplayMode(*physicalId);
     if (preferredBootModeId.has_value()) {
-        mPreferredBootDisplayModeId = static_cast<int32_t>(preferredBootModeId.value());
+        mPreferredBootHwcConfigId = static_cast<int32_t>(preferredBootModeId.value());
     }
 }
 
@@ -90,8 +90,8 @@
     return mId;
 }
 
-int32_t Display::getPreferredBootModeId() const {
-    return mPreferredBootDisplayModeId;
+int32_t Display::getPreferredBootHwcConfigId() const {
+    return mPreferredBootHwcConfigId;
 }
 
 void Display::disconnect() {
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index f542161..2b41ef4 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -232,6 +232,15 @@
     return nullptr;
 }
 
+DisplayModePtr DisplayDevice::getModefromHwcId(uint32_t hwcId) const {
+    const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
+                                 [&](DisplayModePtr mode) { return mode->getHwcId() == hwcId; });
+    if (it != mSupportedModes.end()) {
+        return *it;
+    }
+    return nullptr;
+}
+
 nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
     const auto physicalId = getPhysicalId();
     if (!mHwComposer.isConnected(physicalId)) {
@@ -457,7 +466,13 @@
 }
 
 ui::DisplayModeId DisplayDevice::getPreferredBootModeId() const {
-    return mCompositionDisplay->getPreferredBootModeId();
+    const auto preferredBootHwcModeId = mCompositionDisplay->getPreferredBootHwcConfigId();
+    const auto mode = getModefromHwcId(preferredBootHwcModeId);
+    if (mode == nullptr) {
+        ALOGE("%s: invalid display mode (%d)", __FUNCTION__, preferredBootHwcModeId);
+        return BAD_VALUE;
+    }
+    return mode->getId().value();
 }
 
 void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 3cae30f..e8bd62d 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -227,6 +227,9 @@
     // set-top boxes after a hotplug reconnect.
     DisplayModePtr getMode(DisplayModeId) const;
 
+    // Returns nullptr if the given mode ID is not supported.
+    DisplayModePtr getModefromHwcId(uint32_t) const;
+
     // Returns the refresh rate configs for this display.
     scheduler::RefreshRateConfigs& refreshRateConfigs() const { return *mRefreshRateConfigs; }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 980d1dc..54a777a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1440,8 +1440,15 @@
 
 status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) {
     auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
-        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
-            return getHwComposer().setBootDisplayMode(*displayId, id);
+        if (const auto displayDevice = getDisplayDeviceLocked(displayToken)) {
+            const auto mode = displayDevice->getMode(DisplayModeId{id});
+            if (mode == nullptr) {
+                ALOGE("%s: invalid display mode (%d)", __FUNCTION__, id);
+                return BAD_VALUE;
+            }
+
+            return getHwComposer().setBootDisplayMode(displayDevice->getPhysicalId(),
+                                                      mode->getHwcId());
         } else {
             ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
             return BAD_VALUE;