Skip to main content

Driving restrictions

UX while the vehicle is in motion must minimize distraction. Cabin models driving restrictions as gated interactions: components expose capabilities; compliance allows, denies, or substitutes them based on vehicle UI state.

Goals

  • Reduce eyes-off-road and complex multi-step tasks while driving.
  • Keep essential cabin controls available with glanceable affordances.
  • Provide deterministic gating shared by Compose and Views.
  • Allow OEM programs to tighten Cabin baselines without forking widgets.

Interaction classes

ClassExamplesTypical driving policy
GlanceSpeed, range, now-playing titleAlways allowed; keep short
Simple controlPlay/pause, next track, fan ±Allowed with large targets
ConfigurationDeep settings, pairing, sortingBlocked or deferred while driving
Text entryKeyboard, search typingRestricted / voice-first
Video / animation-heavyMusic videos, elaborate motionRestricted
Safety-criticalHazards, defrost — see safety-criticalAlways available; distinct styling

Components must declare their class in documentation (and later, in metadata).

Gating patterns

Disable vs hide vs substitute

PatternWhen to use
DisableControl remains visible for spatial memory; not activatable
HideNon-essential chrome that adds clutter
SubstituteReplace dense UI with a driving-safe variant (e.g. list → limited list)

Cabin prefers substitute for primary tasks (media browse) and disable for secondary controls that should keep layout stability.

Planned API sketch

// Planned
sealed interface CabinInteraction {
data object OpenKeyboard : CabinInteraction
data object FilterList : CabinInteraction
data class NavigateTo(val destination: String) : CabinInteraction
data class AdjustContinuous(val id: String) : CabinInteraction
}

fun CabinCompliance.gated(
interaction: CabinInteraction,
state: VehicleUiState,
allowed: () -> Unit,
denied: () -> Unit = {},
)

Compose (planned): gated clickable modifiers / composable wrappers.
Views (planned): CabinGatedClickListener / enabled-state binding.

Distraction minimization rules

  1. One primary action per glance cluster — avoid competing CTAs in the driver’s primary visual field.
  2. Short labels — prefer icon + short text; enforce max string lengths when UX restrictions require it (UX restrictions).
  3. No surprise navigation while driving — confirm only when legally / program-required; prefer undo-safe actions.
  4. Motion budget — reduce decorative animation when isDriving (foundations).
  5. No modal traps — dialogs must be dismissible with large targets; avoid stacked modals.

Mapping to platform UX restrictions

Android Automotive exposes CarUxRestrictions. Cabin will adapt those signals into VehicleUiState / UxRestriction (planned Phase 5) so apps are not forced to parse framework details in every screen.

Programs may add stricter rules (e.g. block certain OEM screens above a speed threshold) via policy injection (architecture).

Dual-stack expectations

RequirementComposeViews
Same allow/deny for an interactionYesYes
Visible disabled affordance optionYesYes
Driving-safe alternate layout*Driving composable variantalternate layout XML / CabinDrivingLayout
Logging/analytics hook on deny (optional)CallbackCallback

Acceptance criteria

  • Component documents interaction classes
  • Denied interactions cannot be invoked via click, key, or rotary
  • Driving-safe substitute exists for primary user journeys
  • Behavior identical on Compose and Views for the same state fixture
  • Missing/unknown drive state follows safety-critical defaults