SF: Extract processHotplug from configureLocked

As a precondition, assert that disconnected displays are known, i.e. a
display token exists.

Bug: 241285876
Test: libsurfaceflinger_unittest
Change-Id: I42e183390d29a8fe9b2cd4837a94843efb2e1d2c
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6b4cfa1..96598cd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2649,74 +2649,75 @@
         events = std::move(mPendingHotplugEvents);
     }
 
-    for (const auto& event : events) {
-        std::optional<DisplayIdentificationInfo> info =
-                getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
+    for (const auto [hwcDisplayId, connection] : events) {
+        if (auto info = getHwComposer().onHotplug(hwcDisplayId, connection)) {
+            const auto displayId = info->id;
+            const bool connected = connection == hal::Connection::CONNECTED;
 
-        if (!info) {
-            continue;
+            if (const char* const log =
+                        processHotplug(displayId, hwcDisplayId, connected, std::move(*info))) {
+                ALOGI("%s display %s (HAL ID %" PRIu64 ")", log, to_string(displayId).c_str(),
+                      hwcDisplayId);
+            }
         }
-
-        const auto displayId = info->id;
-        const auto token = mPhysicalDisplayTokens.get(displayId);
-        const char* log;
-
-        if (event.connection == hal::Connection::CONNECTED) {
-            auto [supportedModes, activeMode] = loadDisplayModes(displayId);
-            if (!activeMode) {
-                // TODO(b/241286153): Report hotplug failure to the framework.
-                ALOGE("Failed to hotplug display %s", to_string(displayId).c_str());
-                getHwComposer().disconnectDisplay(displayId);
-                continue;
-            }
-
-            if (!token) {
-                log = "Connecting";
-
-                DisplayDeviceState state;
-                state.physical = {.id = displayId,
-                                  .type = getHwComposer().getDisplayConnectionType(displayId),
-                                  .hwcDisplayId = event.hwcDisplayId,
-                                  .deviceProductInfo = std::move(info->deviceProductInfo),
-                                  .supportedModes = std::move(supportedModes),
-                                  .activeMode = std::move(activeMode)};
-                state.isSecure = true; // All physical displays are currently considered secure.
-                state.displayName = std::move(info->name);
-
-                sp<IBinder> token = sp<BBinder>::make();
-                mCurrentState.displays.add(token, state);
-                mPhysicalDisplayTokens.try_emplace(displayId, std::move(token));
-                mInterceptor->saveDisplayCreation(state);
-            } else {
-                log = "Reconnecting";
-
-                auto& state = mCurrentState.displays.editValueFor(token->get());
-                state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId.
-                state.physical->supportedModes = std::move(supportedModes);
-                state.physical->activeMode = std::move(activeMode);
-                if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
-                    state.physical->deviceProductInfo = std::move(info->deviceProductInfo);
-                }
-            }
-        } else {
-            log = "Disconnecting";
-
-            if (const ssize_t index = mCurrentState.displays.indexOfKey(token->get()); index >= 0) {
-                const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
-                mInterceptor->saveDisplayDeletion(state.sequenceId);
-                mCurrentState.displays.removeItemsAt(index);
-            }
-
-            mPhysicalDisplayTokens.erase(displayId);
-        }
-
-        ALOGI("%s display %s (HAL ID %" PRIu64 ")", log, to_string(displayId).c_str(),
-              event.hwcDisplayId);
     }
 
     return !events.empty();
 }
 
+const char* SurfaceFlinger::processHotplug(PhysicalDisplayId displayId,
+                                           hal::HWDisplayId hwcDisplayId, bool connected,
+                                           DisplayIdentificationInfo&& info) {
+    const auto tokenOpt = mPhysicalDisplayTokens.get(displayId);
+    if (!connected) {
+        LOG_ALWAYS_FATAL_IF(!tokenOpt);
+
+        if (const ssize_t index = mCurrentState.displays.indexOfKey(tokenOpt->get()); index >= 0) {
+            const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
+            mInterceptor->saveDisplayDeletion(state.sequenceId);
+            mCurrentState.displays.removeItemsAt(index);
+        }
+
+        mPhysicalDisplayTokens.erase(displayId);
+        return "Disconnecting";
+    }
+
+    auto [supportedModes, activeMode] = loadDisplayModes(displayId);
+    if (!activeMode) {
+        // TODO(b/241286153): Report hotplug failure to the framework.
+        ALOGE("Failed to hotplug display %s", to_string(displayId).c_str());
+        getHwComposer().disconnectDisplay(displayId);
+        return nullptr;
+    }
+
+    if (tokenOpt) {
+        auto& state = mCurrentState.displays.editValueFor(tokenOpt->get());
+        state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId.
+        state.physical->supportedModes = std::move(supportedModes);
+        state.physical->activeMode = std::move(activeMode);
+        if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
+            state.physical->deviceProductInfo = std::move(info.deviceProductInfo);
+        }
+        return "Reconnecting";
+    }
+
+    DisplayDeviceState state;
+    state.physical = {.id = displayId,
+                      .type = getHwComposer().getDisplayConnectionType(displayId),
+                      .hwcDisplayId = hwcDisplayId,
+                      .deviceProductInfo = std::move(info.deviceProductInfo),
+                      .supportedModes = std::move(supportedModes),
+                      .activeMode = std::move(activeMode)};
+    state.isSecure = true; // All physical displays are currently considered secure.
+    state.displayName = std::move(info.name);
+
+    sp<IBinder> token = sp<BBinder>::make();
+    mCurrentState.displays.add(token, state);
+    mPhysicalDisplayTokens.try_emplace(displayId, std::move(token));
+    mInterceptor->saveDisplayCreation(state);
+    return "Connecting";
+}
+
 void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
     mScheduler->onHotplugReceived(mAppConnectionHandle, displayId, connected);
     mScheduler->onHotplugReceived(mSfConnectionHandle, displayId, connected);