Display stack baseline (iPhone Duo simulator)
Simulator duo-baseline-display (28D2B766-…), iPhone19,4, iOS 27.1 24A94425,
Xcode 27.1. Data: display.json (46085 records, 21 captures), transcripts in
raw/display/states/<capture>-{backboardd,springboard,safari}.txt, posture-driver
output in raw/display/posture/ (screenshots downscaled to 480 px).
How it was collected
probes/display-backboardd.lldb,probes/display-springboard.lldb,probes/display-safari.lldbare generated bysrc/display/gen-probe.zshfromsrc/display/src/{helpers.lldbfrag,*.body,footer.lldbfrag}.- Getters are enumerated, not listed by hand. For each object, the probe takes
every declared property getter plus every zero-argument, non-void method of
the class and its superclasses below NSObject (
class_copyPropertyList,class_copyMethodList). It then drops names with side effects:set*,add*,remove*,invalidate*,_lock_*,_queue_*,_workQueue_*,copy*,create*,start*/stop*, focus and drag lazy getters, and others. The full lists are inhelpers.lldbfrag. The probe calls each getter through a typedobjc_msgSendcast chosen from the method's return type encoding. A getter that returns a block, a pointer, a union or an unknown struct gets a record with an error and is never called. UITraitCollection is the exception: 32 display-relevant getters are named in the probe, because third-party categories add hundreds more. - lldb expressions here cannot use
@try. A getter that raises an exception aborts the whole expression, sosrc/display/iterate.zshtraced the last getter called to a file and added it to a skip list. Only one getter raised:-[CAWindowServerDisplay secureIndicatorsEnabled]. It is recorded with the error "raises an Objective-C exception in this process (not called)". - Each capture:
posture.zsh(swap or status), then the backboardd probe, then the SpringBoard probe (plus MobileSafari for 08-13).src/display/capture.zsh,orient-cycle.zsh,merge.zsh.
Captures
Every posture verified (posture.zsh exit 0: closed → cover lit, book/open → inner lit).
Orientation: what took, and how
- iPhone SpringBoard on the cover is portrait-only, so the home screen gives no orientation data. Captures 08-13 put MobileSafari in front.
- The swap tool's
-deviceOrientation=<o>option is what rotates apps. It drives SpringBoard's pose. It does not change backboardd'sBKOrientationManager.currentRawDeviceOrientation, which stays 0 after boot. BKSHIDServicesSetDeviceOrientationForAutomation(BackBoardServices, called in SpringBoard) changes BK's raw orientation and SpringBoard'sUIDeviceorientation. While the swap tool's pose orientation was landscape, it did not rotate the app back. Captures made that way were discarded (raw/display/states/discarded/). It was last called with 1, so captures 08-10 show raw orientation 1; after the reboot it is 0 again.- Mapping that was observed (Safari = the app's own
UIDeviceand scene orientation):
On the inner display the interface orientation is a quarter turn from the
device orientation: holding the device in portrait gives landscape UI on the
inner panel. The orientation field in the records is the swap option name.
Cover vs inner: where they differ in kind
All values are from 02-open-after-closed unless a capture is named. Both
displays are always present and always connected. Only the power state and the
lit panel follow the posture.
For the VM's two-display path, these are the identities the inner display must reproduce:
- FBS identity
Unknown.main[3]: type 7, displayID 3, not main, its own root identity, UIKit-main-like, always connected. - CA
LCD-1/primary-1with tag 65536 (0x10000). extendedPropertieswith DisplayRotation 270 and DeviceSurfaceType 2.- BKS surfaceType 2.
The cover is Main, displayId 1, tag 0, surface type 1, and it is always
mainScreen and mainDisplay.
Posture-dependent values (home screen, portrait)
Book and open are identical in every display-stack value (02 vs 04, 05 vs 06). CADisplay seed, bounds, modes and identities do not change with the posture.
History-dependent values
-
The inner UIScreen before and after the first unfold. At boot (01, and again 11 after a reboot):
- bounds 669×951 and
_interfaceOrientation0 (orientation: unknown (0)) _peripheryInsetst/b- traitCollection without size classes (0/0)
From the first unfold on, in every posture including closed (02-07):
- bounds 951×669 and
_interfaceOrientation4 _peripheryInsetsl/r- horizontal/vertical size class Regular (2/2)
Closed after open (03, 07) keeps the post-unfold values. The FBS current configuration seed goes 3 → 5 at the first unfold. The inner CAWindowServerDisplay is
landscapeLeft, the CADisplayrot90, and BK holds orientation 4 for the inner UUID, already at boot. - bounds 669×951 and
-
The cover UIScreen keeps the last orientation the cover had.
- After 08-closed-LL/LR it stays 678×466 with
_interfaceOrientation4/3 while the inner is in use (09-book-LL/LR, 13-book-LL/LR). Thebookanchor swap to closed inherits the current device orientation, so the cover rotates first. 12-open-LL/LR(no anchor) keeps the cover at 466×678.
- After 08-closed-LL/LR it stays 678×466 with
-
The SpringBoard inner primary scene orientation with device portrait.
- It is 1 when the swap unfolded from closed: 09-book-P, 12-open-P, and 02/04 on the home screen.
- It is 4 when the swap started on the inner: 10-open-P, 13-book-P.
- Safari is at io 4 in both cases, and
UIApplication.activeInterfaceOrientationis 4.
-
Display UUIDs change on every boot. CADisplay uniqueId/UUID, FBS hardwareIdentifier, CAWindowServerDisplay systemIdentifiers and FramebufferIdentifier all change. Compare by name, displayId and identity, never by UUID.
Repeatability: closed 03 vs 07, open 02 vs 05 and book 04 vs 06 match except for the volatile fields (touch-stream creation times).
Digitizer → display mapping (backboardd)
From _queue_perDisplayInfo and _queue_displayUUIDForDigitizerService::
Each BKDirectTouchState._interfaceOrientation follows its display's BK
orientation: the cover 1, the inner 4 (1 or 2 when the inner app is rotated).
There is no AOP or pencil digitizer, and no chamois display.
Incident: at 14:45:36 every CoreDevice HID service disappeared from backboardd ("*** lost main display digitizer **", IOHIDEventSystem connections removed). The host side caused it; this sim did nothing at that moment. It left 10-open-LL/LR without digitizers. Those two captures were discarded, the sim was rebooted, and the open orientations were redone as 12-open-.
Other values (both displays unless stated)
[CAWindowServer serverIfRunning]: 5 displays (LCD 1398×2034, TVOut 0×0, LCD-1 2007×2853, Wireless 0×0, Resizable 0×0), rendererFlags 3, not secure, mirroring off,lss_extendedDisplaysempty,_lss_primaryDisplayLCD.BKDisplayRenderOverlayManager: one active overlay,BKDisplayRenderOverlaySpinny(gear, level -1, background) on the cover, in every capture.lockedOrientation0,backlightLockedNO.BKDisplayBrightnessController: brightnessLevel 0.5, curve 1, ALS / auto brightness / level control unavailable.UIScreen.brightness0.5. No per-display brightness getter exists.UISDisplayContext defaultContext: the cover (Main) configuration; displayEdgeInfo and exclusionArea are nil.
Missing, nil and errored
- nil on both panels:
- CADisplay: productName, containerId, externalDisplayAttributes,
allowed/preferred/supportedHDRModes, availablePresets, currentPreset,
_copyDebugProperties(NULL) - CADisplayStateControl:
_copyAll{Power,FrameRate}AssertionInfo - CAWindowServerDisplay: brightnessCapabilities, virtualDisplayMode, averagePixelConstraints, TVMode, cloneMaster, cursorDictionary
- CAWindowServer: displayExternalSyncManager
- FBS:
FBSDisplayIdentity.uniqueIdentifier,FBSDisplayConfiguration.uniqueIdentifier,originatingConfiguration - UIScreen: mirroredScreen,
_overrideTraitCollection,__eventDisplay,_initialDisplayContext,_previousHardwareIdentifier, focusGroupIdentifier +[UIScreen _carScreen],UITraitCollection._systemDisplayIdentifier,UISDisplayContext.displayEdgeInfo/exclusionArea- BK: mainDisplayAOP/PencilDigitizerService, chamoisDisplayUUID,
_frozenDisplayIDs
- CADisplay: productName, containerId, externalDisplayAttributes,
allowed/preferred/supportedHDRModes, availablePresets, currentPreset,
- Not called (type):
- CADisplay.timingsControl (
^v) - CAWindowServerDisplay blend/displayColorSpace (
^{CGColorSpace}), detachingDisplay, systemGamma and blackpointAdaptation (CGColorTRCunion), the six callback blocks - UIScreen
_fallbackTraitCollection(^v)
- CADisplay.timingsControl (
- Raises:
CAWindowServerDisplay.secureIndicatorsEnabled. - Declared but not implemented: UIScreen
_isEligibleForFocusInteraction,_isEligibleForFocusOcclusion,_linearFocusMovementSequences,_preferredFocusMovementStyle,traitOverrides(protocol properties). - Absent APIs:
- CAWindowServerDisplay has no
contextIdsgetter. The probe recordscontextIdAtPosition:at the panel centre instead; it is volatile. - There is no
CADisplay.maximumFramesPerSecond,colorGamutoroverscangetter. The equivalents arerefreshRate,currentMode.colorGamutandoverscanAmount/overscanAdjustment. extendedPropertiesexists only on CAWindowServerDisplay, not on FBS._UIScreenDisplayConfigurationdoes not exist; it isUIScreen.displayConfiguration/fbsDisplay.SpringBoard._accessibilityFrontMostApplication(a probe convenience) is not available.
- CAWindowServerDisplay has no
Volatile fields (ignore when comparing)
- CAWindowServerDisplay nextWakeupTime, previousVBL, vblDelta and contextIdAtPosition
- pointer addresses inside descriptions
- touch-stream client creationTime
- brightness freeze times
- seeds: CADisplay seed and FBS config seed rise with rotations and swaps