From 4a42d43bf32ba88e0867717d22bae318ac00de5b Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Wed, 12 Feb 2020 20:22:26 +0100 Subject: SF: Update display properties on hotplug connect When a hotplug connect event for already connected display is received, destroy and recreate the display device in SF, then send a "hotplug connect" event to Display manager. This way display properties will be updated. Bug: 143451809 Test: atest libsurfaceflinger_unittest Test: atest SurfaceFligner_test Test: atest CompositionTest Test: Manually on device: 2. adb shell dumpsys display 3. unplug primary display 4. plug another display 5. adb shell dumpsys display Test: Manually on device: 1. disconnect and reconnect display 2. power off and on the screen 3. make sure the device didn't crash Merged-In: I89996d9340f6570fa5ae0cc0977eaba7a2d3693c Change-Id: I89996d9340f6570fa5ae0cc0977eaba7a2d3693c (cherry picked from commit 700e639f7d283987fb7b994a038dc0ca5dba3dbf) --- services/surfaceflinger/SurfaceFlinger.cpp | 42 ++++++++++++++++++------------ 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2da92b3145..34d6d3133c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2385,7 +2385,8 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { } DisplayDeviceState state; - state.physical = {displayId, getHwComposer().getDisplayConnectionType(displayId)}; + state.physical = {displayId, getHwComposer().getDisplayConnectionType(displayId), + event.hwcDisplayId}; state.isSecure = true; // All physical displays are currently considered secure. state.displayName = info->name; @@ -2394,6 +2395,12 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { mPhysicalDisplayTokens.emplace(displayId, std::move(token)); mInterceptor->saveDisplayCreation(state); + } else { + ALOGV("Recreating display %s", to_string(displayId).c_str()); + + const auto token = it->second; + auto& state = mCurrentState.displays.editValueFor(token); + state.sequenceId = DisplayDeviceState{}.sequenceId; } } else { ALOGV("Removing display %s", to_string(displayId).c_str()); @@ -2571,20 +2578,17 @@ void SurfaceFlinger::processDisplayAdded(const wp& displayToken, producer = bqProducer; } - if (displaySurface != nullptr) { - mDisplays.emplace(displayToken, - setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, - displaySurface, producer)); - if (!state.isVirtual()) { - LOG_ALWAYS_FATAL_IF(!displayId); - dispatchDisplayHotplugEvent(displayId->value, true); - } + LOG_FATAL_IF(!displaySurface); + const auto display = setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, + displaySurface, producer); + mDisplays.emplace(displayToken, display); + if (!state.isVirtual()) { + LOG_FATAL_IF(!displayId); + dispatchDisplayHotplugEvent(displayId->value, true); + } - const auto displayDevice = mDisplays[displayToken]; - if (displayDevice->isPrimary()) { - mScheduler->onPrimaryDisplayAreaChanged(displayDevice->getWidth() * - displayDevice->getHeight()); - } + if (display->isPrimary()) { + mScheduler->onPrimaryDisplayAreaChanged(display->getWidth() * display->getHeight()); } } @@ -2595,7 +2599,7 @@ void SurfaceFlinger::processDisplayRemoved(const wp& displayToken) { display->disconnect(); if (!display->isVirtual()) { - LOG_ALWAYS_FATAL_IF(!displayId); + LOG_FATAL_IF(!displayId); dispatchDisplayHotplugEvent(displayId->value, false); } } @@ -2608,13 +2612,19 @@ void SurfaceFlinger::processDisplayChanged(const wp& displayToken, const DisplayDeviceState& drawingState) { const sp currentBinder = IInterface::asBinder(currentState.surface); const sp drawingBinder = IInterface::asBinder(drawingState.surface); - if (currentBinder != drawingBinder) { + if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) { // changing the surface is like destroying and recreating the DisplayDevice if (const auto display = getDisplayDeviceLocked(displayToken)) { display->disconnect(); } mDisplays.erase(displayToken); + if (const auto& physical = currentState.physical) { + getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id); + } processDisplayAdded(displayToken, currentState); + if (currentState.physical) { + initializeDisplays(); + } return; } -- cgit v1.2.3-59-g8ed1b