@enfinitos/sdk-automotive
EnfinitOS reference SDK for the AUTOMOTIVE substrate. Five sibling implementations target the four real 2026 in-vehicle surfaces (CarPlay, Android Auto, Android Automotive OS, OEM mini-apps) plus a shared TypeScript core. All native wrappers delegate the rights/policy/proof plane to @enfinitos/sdk-renderer- core and enforce the BehaviouralConstraint automotive rules (DONT_DISPLAY_WHILE_MOVING, PASSENGER_DISPLAY_ONLY, INTEGRATE_WITH_VEHICLE_DISTRACTION_SYSTEM, DRIVER_ATTENTION_REQUIRED, REQUIRE_HANDS_FREE) shipped earlier in the rights bounded context.
Architecture
┌───────────────────────────────────────┐
│ @enfinitos/sdk-renderer-core (TS) │
│ resolve/grant/event-ingest/health │
└───────────────────────────────────────┘
▲
│
┌─────────────────┴─────────────────┐
│ automotive ts-core (this pkg) │
│ AutomotiveClient + Safety │
│ Enforcer + SpeedMonitor │
└─────────────────┬─────────────────┘
│ bridges
┌─────────────────┬──────────────────┼──────────────────┬──────────────────┐
│ │ │ │ │
┌───────┐ ┌───────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
│CarPlay│ │Android Aut│ │ AAOS 14 │ │ MBUX Mini │ │ BMW Mini │
│ (iOS) │ │CarAppLib │ │full Android│ │ Apps │ │ Apps │
└───────┘ └───────────┘ └────────────┘ └────────────┘ └────────────┘
│ │ │ │ │
CarPlay Jetpack AAOS 14 media MBUX SDK web BMW SDK web
entitlements CarApp session, full wrapper (host wrapper (host
(audio, comms, library 1.4+, Android app on URL inside URL inside
navigation, limited UX, head unit, Auto- vehicle's web vehicle's web
parking, EV- OEM-projected motive intents, container) container)
charging, food) surface CarUx restrictions
The TS core is the canonical rights/proof layer. Each native wrapper translates substrate-specific UX templates onto the renderer-core proof-of-play events and enforces in-cab safety locks via the shared SafetyEnforcer.
Tesla intentionally has no code; the closed MCU plug-in framework is documented in oem/tesla/README.md.
Getting started
TypeScript core
pnpm add @enfinitos/sdk-automotive
import { AutomotiveClient } from "@enfinitos/sdk-automotive";
const client = new AutomotiveClient({
apiBaseUrl: "https://api.enfinitos.com",
authToken: jwt,
deviceId: vinHash,
surface: "carplay",
vehicleProfile: {
isMoving: () => vehicleApi.speedMps() > 0.5,
speedKph: () => vehicleApi.speedKph(),
isDriverFocused: () => vehicleApi.driverGaze() === "on-road",
},
});
await client.start();
const asset = await client.resolveNext({ surfaceId: "audio-pre-roll" });
if (asset) {
await client.beginPlayback(asset);
await client.reportPlayStarted(asset, new Date());
}
The TS core enforces every BehaviouralConstraint automotive rule on the client side before delegating to the platform's rendererClient — a moving vehicle that requests a visual asset has its request automatically downgraded to audio-only (or refused outright if no audio variant exists). The platform's rightsAuthorityGate is the canonical enforcement point; the client-side check is an early-rejection optimisation for the latency-critical in-cab case.
CarPlay (iOS)
import EnfinitOSCarPlay
class SceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
var client: EnfinitOSCarPlayClient!
func templateApplicationScene(
_ scene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController
) {
client = EnfinitOSCarPlayClient(
apiBaseUrl: URL(string: "https://api.enfinitos.com")!,
authToken: jwt,
vehicleId: vinHash,
interfaceController: interfaceController,
)
Task { try await client.start() }
}
}
Android Auto
class AcmeCarAppService : CarAppService() {
override fun createHostValidator() = HostValidator.ALLOW_ALL_HOSTS_VALIDATOR
override fun onCreateSession(): Session = AcmeSession()
}
class AcmeSession : Session() {
private lateinit var client: EnfinitOSAndroidAutoClient
override fun onCreateScreen(intent: Intent): Screen {
client = EnfinitOSAndroidAutoClient(
carContext = carContext,
apiBaseUrl = "https://api.enfinitos.com",
authToken = jwt,
)
return client.rootScreen()
}
}
Android Automotive OS
val client = EnfinitOSAAOSService(
context = applicationContext,
apiBaseUrl = "https://api.enfinitos.com",
authToken = jwt,
vehicleProfile = AAOSVehicleProfile.fromCarPropertyManager(carPropertyManager),
)
client.start()
val asset = client.fetchNext(AAOSContentRequest(surfaceId = "media-pre-roll"))
client.playMediaItem(asset)
MBUX Mini Apps (Mercedes)
import { EnfinitOSMBUXMiniApp } from "@enfinitos/sdk-automotive/oem/mbux";
const app = new EnfinitOSMBUXMiniApp({
apiBaseUrl: "https://api.enfinitos.com",
authToken: jwt,
miniAppManifest: { id: "com.acme.mbux", category: "infotainment" },
});
await app.init();
BMW Mini Apps
import { EnfinitOSBMWMiniApp } from "@enfinitos/sdk-automotive/oem/bmw-mini-apps";
const app = new EnfinitOSBMWMiniApp({
apiBaseUrl: "https://api.enfinitos.com",
authToken: jwt,
iDriveVersion: 9,
});
await app.init();
2026 platform notes
CarPlay
- CarPlay 2 is rolling out on selected Aston Martin and Porsche models but the broad-fleet surface is still CarPlay 1's template-driven UI. This SDK targets CarPlay 1; a CarPlay 2 surface lives in
spatial-ar/carplay-2/(not in scope here). - Entitlements are issued case-by-case by Apple. CarPlay-eligible app categories in 2026 are: audio, communication, navigation, parking, fueling, EV charging, quick-food ordering, driving task. No "general advertising" category exists; EnfinitOS-backed CarPlay scenes must fall in one of these. The README under
carplay/calls out which entitlement each integration pattern requires. - No free-form UIKit. CarPlay templates are
CPListTemplate,CPGridTemplate,CPNowPlayingTemplate,CPSearchTemplate,CPInformationTemplate,CPVoiceControlTemplate,CPContactTemplate. The SDK exposes these as type-safe builders; arbitrary HTML/video is not possible. - Swift Concurrency throughout. Minimum target iOS 17 + CarPlay with the matching iOS version; CarPlay-specific APIs use
async throws.
Android Auto
- Jetpack
CarAppLibrary1.4+ is the surface.androidx.car.appartifacts. Templates areListTemplate,GridTemplate,MessageTemplate,NavigationTemplate,PlaceListMapTemplate,RoutePreviewNavigationTemplate,SignInTemplate, plus category-restricted ones (MapTemplaterequires the navigation category). - Template restrictions are enforced by the host (Google's Android Auto app). Apps cannot draw outside the templates; attempts to composite arbitrary
Views are rejected on session start. - Min Car App API Level 7 (Android Auto 13+, native to all Android 12+ phones). Lower API levels (CarPlay-style legacy media apps) are out of scope.
Android Automotive OS (AAOS)
- Full Android app surface — AAOS is "Android-the-OS" running on the head unit. The SDK exposes the full
EnfinitOSRendererprimitives because the app can render arbitraryActivitys. CarUxRestrictionsenforcement is mandatory. When the vehicle is in motion the OS broadcasts aCarUxRestrictionsbundle that forbids certain UI patterns (text > 60 chars, video, scrolling, keyboard input). The SDK subscribes viaCarUxRestrictionsManagerand pushes the restriction state intoSafetyEnforcer, which automatically downgrades video to audio-only and clips text.CarPropertyManageris the speed source —PERF_VEHICLE_SPEEDis the canonical signal (m/s, ground speed). Engine-derived speed estimates are not allowed for safety-critical paths because they drift at low speeds.- AAOS 14 is the current floor. AAOS 12 still ships in some 2024 vehicles but doesn't expose the granular
RestrictedAppManagerprimitives we depend on; minimum target is AAOS 14.
Mercedes MBUX Mini Apps
- MBUX Mini Apps SDK is web-based — apps ship as a hosted URL packaged into a MBUX-signed manifest. The container is a Chromium-based web view with restricted JS APIs.
- No client-side video playback while moving — the SDK rejects video assets when MBUX reports
vehicleState.motionState === "DRIVING".
BMW Mini Apps (iDrive 8/9)
- BMW Mini Apps SDK is similarly web-based — iDrive 8 introduced the Mini Apps container; iDrive 9 (in 2026 production vehicles) expands it with native messaging hooks. The SDK detects which generation it's running on via the injected
BMWMiniAppHostJS bridge.
Tesla
- Closed platform. No public SDK. Integration with Tesla's in-cab surface is via Tesla's internal MCU media plug-in framework (private). The
oem/tesla/README.mddocuments the integration contract for partners that have Tesla's private SDK; this package ships no code targeting it.
Endpoint surface
| SDK call | Platform endpoint | Status |
|---|---|---|
resolveNext | POST /runtime/resolve then POST /runtime/grant | existing |
reportPlayStarted/Ended/Click/Conversion | POST /runtime/event-ingest | existing |
reportSafetyDowngrade (audio→silenced, video→audio) | POST /runtime/event-ingest with kind=automotive-safety-downgrade | existing |
reportVehicleProfile (speed, distraction state) | POST /runtime/event-ingest with kind=automotive-telemetry | needs future API work |
| CarPlay scene template | OS-mediated; no platform call | existing |
AAOS CarUxRestrictions push | OS-mediated; SDK consumes only | existing |
Test plan
- TS core: Vitest under
ts-core/src/__tests__/. - CarPlay: XCTest under
carplay/Tests/EnfinitOSCarPlayTests/. - Android Auto: JUnit 4 under
android-auto/src/test/. - AAOS: JUnit 4 under
android-automotive/src/test/. - OEM: Vitest (TS sources only).