ADR-0006: Root-scoped overlay backend selection
- Status: Accepted
- Date: 2026-08-09
- Supersedes: the
viewcompose-overlay-androidretirement/rename portions of ADR-0002 and ADR-0003
Context
UI Foundation already separated declarative overlay requests, session identity, queue policy, and
captured surface content from Android presentation. The first Android backend nevertheless mixed
generic Dialog, PopupWindow, Toast, nested render containers, Material Snackbar, and Material
bottom sheet in one artifact.
The five-layer hard cut renamed that artifact to viewcompose-overlay-material3-android. This made
Material ownership visible, but it also assigned generic Android transport to a Material module.
Host Android then discovered an entire host through ServiceLoader and selected the first provider.
Consequently a neutral or One UI root could receive Material behavior merely because the Material
artifact was present on the runtime classpath.
Overlay selection must agree with the root's Context, token, recipe, and diagnostic snapshot. It must also preserve Android window lifecycle and native behavior without adding design-system branches to UI Foundation, Host Android, or Renderer.
Decision
- Reactivate
viewcompose-overlay-androidat0.1.0-alpha04as the only Material-free Android overlay transport. This is a breaking semantic restoration, not a compatibility facade. - The neutral artifact owns Android Dialog, PopupWindow, Toast, anchor observation, coordinate placement, nested render-container adaptation, and root/session cleanup.
- Snackbar and modal bottom sheet are narrow presenter slots. Missing presenters are explicit
Unsupportedresults; the neutral host never substitutes Material. viewcompose-overlay-material3-androidowns only Material Snackbar andBottomSheetDialogpresenters plus a thin adapter that composes them with the neutral host.- Neutral
setUiContentand navigation roots construct the neutral host explicitly.setMaterial3UiContentconstructs the Material adapter explicitly. Classpath order does not select design behavior. - Host Android retains
ServiceLoaderonly for custom low-level hosts discovering the single neutral provider. Zero providers returns no-op; multiple providers fail deterministically. - Design-system snapshots use
UiIntegrationAttributionto report capability, transport, presenter, conformance, and fallback. Delayed overlay content captures that immutable snapshot. - A design system receives another Activity/Fragment entry module only when it must resolve a
distinct Android Context before View construction. Token/recipe-only systems use the neutral
root and do not duplicate
setUiContentextensions.
Consequences
- Neutral and One UI dependency graphs contain no Material Components through overlay defaults.
- Material applications retain a one-dependency, one-host-call path through
viewcompose-material3-android. - Custom Material hosts must construct the Material adapter explicitly; the old Material service provider is removed.
- Existing consumers of
viewcompose-overlay-android:0.1.0-alpha03must migrate public package references and cannot assume Material Snackbar or bottom-sheet behavior from that coordinate. - One UI Snackbar and modal bottom sheet remain explicitly unsupported until verified One UI recipes justify presenters. Silent Material fallback is forbidden.
- Historical tags and generated documentation remain immutable even though the Maven coordinate is active again.
Rejected alternatives
Keep the Material whole-host provider
Rejected because provider order is process-global and cannot prove which design-system snapshot owns a root or delayed overlay.
Publish one Activity/Fragment extension module per design system
Rejected because token-only systems do not need a different Android Context. Duplicating lifecycle, saved-state, and render-session entry points would increase drift without adding capability.
Put all overlay presenters in UI Foundation
Rejected because Android windows and Material widgets are platform/integration details. UI Foundation must remain the request, queue, session, and captured-content owner.
Keep viewcompose-overlay-android retired and introduce another neutral coordinate
Rejected by project decision. Restoring the clear generic coordinate is preferable to adding a
platform or host qualifier, provided the breaking semantic change is explicit and versioned.