In Android 9 (and lower), SurfaceFlinger and DisplayManagerService
assumed the existence of at most two physical displays with hard-coded IDs 0
and 1. As described in
Static
Display Identifiers, SurfaceFlinger now leverages
a Hardware Composer (HWC) API to generate stable display IDs, which enables it
to manage an arbitrary number of physical displays.
The framework can look up the IBinder
token for a physical
display via SurfaceControl#getPhysicalDisplayToken
after obtaining
the 64-bit display ID from SurfaceControl#getPhysicalDisplayIds
or
from a DisplayEventReceiver
hotplug event.
In Android 10, primary internal display is
TYPE_BUILT_IN
, and all secondary displays are flagged as
TYPE_HDMI
regardless of connection type. Therefore, additional
internal displays are currently treated as external. As a workaround,
device-specific code can make assumptions about
DisplayAddress.Physical#getPort
if the HWC is known and the port
allocation logic is predictable.
Implementation
Previously, displays were identified by 32-bit IDs, where 0 is the internal
display, 1 is the external display, [2, INT32_MAX] are HWC virtual displays, and
-1 represents an invalid display or a non-HWC virtual display. For
SurfaceFlinger and DisplayManagerService
to track more than two
displays and recognize previously seen displays, displays should be given stable
and persistent IDs.
If the HWC supports IComposerClient.getDisplayIdentificationData
and provides display identification data, SurfaceFlinger parses the EDID
structure and allocates stable 64-bit display IDs for physical and HWC virtual
displays. The IDs are expressed using an option type, where the null value
represents an invalid display or non-HWC virtual display. Without HWC support,
SurfaceFlinger falls back to legacy behavior with at most two physical
displays.