AutographComposeHosts

The set of views whose content belongs to a Compose capture pipeline, so the native pipeline can stay off it.

A tap inside a ComposeUIViewController is visible to both pipelines — autograph-compose reaches it by walking the accessibility tree CMP bridges its semantics into, and the native pipeline reaches it because UIView.hitTest delivers the touch straight through the host view. Without a boundary the two would each report it and every Compose tap would be counted twice. autograph-compose registers its host view; containsAny lets the native side drop any tap whose path crosses one.

The two sides pass different kinds of path to containsAny, and it works on either because it only ever asks whether a registered view is among the nodes: since #191 the native pipeline passes the hitTest superview chain (see NativeHitTestResolution.kt), while the Compose side passes a deepestAccessibilityHitPath walk.

This is a static condition, not a race. The alternative — "did the Compose pipeline already report this tap?" — would make the outcome depend on which recognizer fired first. Asking instead "does this tap land under Compose-owned content?" has one answer regardless of ordering, and it holds even when the Compose side declines to report the tap at all.

That last part is the privacy-relevant one. The invariant is content under a Compose host belongs to the Compose pipeline exclusively — not content the Compose pipeline reported. A hybrid app can run Compose with autocapture off and the native pipeline on; if registration were conditional on the Compose autocapture flag, the native walk would descend into Compose's bridged tree and capture elements the developer excluded with Modifier.autographIgnore(). Registration must therefore happen whenever a Compose host exists, independent of that flag.

Process-global by design. "This view hosts Compose" is a fact about the view, not about a tracker, and the two sides have no other place to meet: the Compose host registers from inside a composition and the native pipeline consults it from a gesture recognizer, with no shared owner to thread an instance through.

The ref-counted, weak, pointer-personality bookkeeping lives in WeakViewRegistry; this holds its own instance, separate from AutographIgnoredViews's, deliberately (see there). Main thread only.

Functions

Link copied to clipboard

Whether path — a hit path from deepestAccessibilityHitPath — crosses a registered host, i.e. whether the tap that produced it landed on Compose-owned content.

Link copied to clipboard
fun register(view: UIView)

Marks view and everything under it as owned by the Compose pipeline, until a matching unregister. Registrations nest: callers pair their own, and the view stays owned until the last one is released.

Link copied to clipboard
fun unregister(view: UIView)

Releases one register. Safe to call for a view that was never registered, and — deliberately — for one already fully released: an unbalanced extra call must not push the count negative and re-arm nothing.