SF: Fix a sporadic crash during multi-display boot
The Scheduler is created when the first commit adds the primary display,
and accessed whenever a commit adds a physical display. Transactions are
ordered by display token, which is an arbitrary address.
In a multi-display boot, the addition of the primary display could be
reordered after other displays, causing a crash when the Scheduler is
accessed before creation.
As a short-term workaround until Scheduler initialization is decoupled
from commit of display transactions, commit the primary display first.
Bug: 244442572
Test: Boot
Change-Id: I62c4b5299de329a02e60d5f2529ed49907d74415
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f7684a0..9b4e736 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -374,7 +374,20 @@
const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
LayerVector layersSortedByZ;
- DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
+
+ // TODO(b/241285876): Replace deprecated DefaultKeyedVector with ftl::SmallMap.
+ DefaultKeyedVector<wp<IBinder>, DisplayDeviceState> displays;
+
+ std::optional<size_t> getDisplayIndex(PhysicalDisplayId displayId) const {
+ for (size_t i = 0; i < displays.size(); i++) {
+ const auto& state = displays.valueAt(i);
+ if (state.physical && state.physical->id == displayId) {
+ return i;
+ }
+ }
+
+ return {};
+ }
bool colorMatrixChanged = true;
mat4 colorMatrix;
@@ -695,7 +708,7 @@
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
- void initScheduler(const sp<DisplayDevice>& display) REQUIRES(mStateLock);
+ void initScheduler(const sp<const DisplayDevice>&) REQUIRES(mStateLock);
void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock);
void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod);
@@ -1027,7 +1040,7 @@
void onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay)
REQUIRES(mStateLock, kMainThreadContext);
- void onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay);
+ void onActiveDisplaySizeChanged(const sp<const DisplayDevice>&);
/*
* Debugging & dumpsys