SF: Prevent crashes in onRefreshRateChangedDebug
The AIDL thread reads HWComposer state without locks, but there may be
a concurrent write on the main thread. Also, the display may no longer
exist by the time the scheduled task runs.
Bug: 241285876
Test: presubmit
Change-Id: I3460e23cad2a884250bebcd58b1eaec9cd309858
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 14dfdf5..65e4f68 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2225,19 +2225,20 @@
void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) {
ATRACE_CALL();
- if (const auto displayId = getHwComposer().toPhysicalDisplayId(data.display); displayId) {
- const char* const whence = __func__;
- static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
- const Fps fps = Fps::fromPeriodNsecs(getHwComposer().getComposer()->isVrrSupported()
- ? data.refreshPeriodNanos
- : data.vsyncPeriodNanos);
- ATRACE_FORMAT("%s Fps %d", whence, fps.getIntValue());
- const auto display = getDisplayDeviceLocked(*displayId);
- FTL_FAKE_GUARD(kMainThreadContext,
- display->updateRefreshRateOverlayRate(fps, display->getActiveMode().fps,
- /* setByHwc */ true));
- }));
- }
+ const char* const whence = __func__;
+ static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
+ kMainThreadContext) {
+ if (const auto displayIdOpt = getHwComposer().toPhysicalDisplayId(data.display)) {
+ if (const auto display = getDisplayDeviceLocked(*displayIdOpt)) {
+ const Fps fps = Fps::fromPeriodNsecs(getHwComposer().getComposer()->isVrrSupported()
+ ? data.refreshPeriodNanos
+ : data.vsyncPeriodNanos);
+ ATRACE_FORMAT("%s Fps %d", whence, fps.getIntValue());
+ display->updateRefreshRateOverlayRate(fps, display->getActiveMode().fps,
+ /* setByHwc */ true);
+ }
+ }
+ }));
}
void SurfaceFlinger::configure() {