### Install Dependencies Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/apps/example/README.md Run this command to install project dependencies. ```bash yarn install ``` -------------------------------- ### Install react-native-config Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Install the `react-native-config` package to manage environment variables for different build variants. ```bash yarn add react-native-config ``` -------------------------------- ### Install React Native Auto Play Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Install the package and its peer dependencies using yarn. For iOS, additional pod installation is required. ```bash yarn add @iternio/react-native-auto-play react-native-nitro-modules ``` ```bash cd ios && pod install && cd .. ``` -------------------------------- ### ListTemplate Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Example of how to instantiate and use the ListTemplate for displaying lists and menus. ```APIDOC ## ListTemplate ### Description Used for displaying lists and menus. It supports sections and radio/toggle rows. ### Usage ```ts new ListTemplate({ title: { text: 'Destinations' }, sections: [{ type: 'default', title: 'Recent', items: [{ type: 'default', title: { text: 'Home' }, onPress: () => {} }] }], headerActions: { android: { startHeaderAction: { type: 'back', onPress: () => {} } } }, }).push(); ``` ``` -------------------------------- ### MapTemplate Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Example of how to instantiate and use the MapTemplate for navigation and map rendering. ```APIDOC ## MapTemplate ### Description Used for navigation and map rendering. It serves as the root template and supports map buttons and navigation APIs. ### Usage ```ts const map = new MapTemplate({ component: MapScreen, onStopNavigation: () => {}, headerActions: { android: [{ type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }] }, }); map.setRootTemplate(); ``` ``` -------------------------------- ### ListTemplate Example Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Create and push a ListTemplate for displaying lists or menus. Supports sections and radio/toggle rows. ```typescript new ListTemplate({ title: { text: 'Destinations' }, sections: [{ type: 'default', title: 'Recent', items: [{ type: 'default', title: { text: 'Home' }, onPress: () => {} }] }], headerActions: { android: { startHeaderAction: { type: 'back', onPress: () => {} } } }, }).push(); ``` -------------------------------- ### Create AutoPlay Experience Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configure templates and React components for your automotive UI. This example sets up a MapTemplate with header actions and registers components for the Dashboard and Cluster. ```tsx // src/AutoPlay.tsx import { AutoPlayCluster, CarPlayDashboard, HybridAutoPlay, MapTemplate, useMapTemplate, } from '@iternio/react-native-auto-play'; import React, { useEffect } from 'react'; import { Platform, Text, View } from 'react-native'; // A simple component that can be reused across different screens const MyCarScreen = ({ title }: { title: string }) => ( {title} ); // The React component to be rendered inside the MapTemplate const MapScreen = () => { const mapTemplate = useMapTemplate(); useEffect(() => { // Show an alert on the car screen when the component mounts mapTemplate?.showAlert({ id: 'welcome-alert', title: { text: 'Welcome!' }, subtitle: { text: 'Your app is now running on the car screen.' }, durationMs: 5000, priority: 'low', }); }, [mapTemplate]); return ; }; const registerAutoPlay = () => { const onConnect = () => { // When a car is connected, create a MapTemplate and set it as the root const rootTemplate = new MapTemplate({ component: MapScreen, // Render our map component headerActions: { android: [ { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => console.log('Search pressed'), }, { type: 'image', image: { name: 'cog', type: 'glyph' }, onPress: () => console.log('Settings pressed'), }, ], ios: { leadingNavigationBarButtons: [ { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => console.log('Search pressed'), }, ], trailingNavigationBarButtons: [ { type: 'image', image: { name: 'cog', type: 'glyph' }, onPress: () => console.log('Settings pressed'), }, ], }, }, }); rootTemplate.setRootTemplate(); }; // Register components for the Dashboard and Cluster if (Platform.OS === 'ios') { CarPlayDashboard.setComponent(() => ); } AutoPlayCluster.setComponent(() => ); // Add listeners for car connection and disconnection events HybridAutoPlay.addListener('didConnect', onConnect); HybridAutoPlay.addListener('didDisconnect', () => { console.log('Car disconnected'); }); }; export default registerAutoPlay; ``` -------------------------------- ### Expo Splash Screen Patch Example Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Example of how to use the patch for expo-splash-screen to hide the splash screen for specific scenes. ```APIDOC ## Expo Splash Screen Patch (iOS) ### Description This example demonstrates how to use the provided patch for `expo-splash-screen` to manage splash screen visibility when using scenes with `react-native-auto-play`. ### Usage Apply the patch included in the `patches/` directory using `patch-package`. After applying the patch, you can hide the splash screen for a specific scene by passing the module name to the `hide` or `hideAsync` function. ### Code Example ```tsx import { hideAsync } from 'expo-splash-screen'; import { AutoPlayModules } from '@iternio/react-native-auto-play'; // Hide the splash screen for the main app hideAsync(AutoPlayModules.App); // Hide the splash screen for the CarPlay screen hideAsync(AutoPlayModules.AutoPlayRoot); ``` ``` -------------------------------- ### Header Actions Configuration Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration examples for header actions on Android and iOS, differentiating between standard templates and MapTemplate. ```APIDOC ## Header Actions Configuration ### For List/Grid/Information/Search/Message/SignIn templates on Android: Use the structured object format for `headerActions`. ```ts const headerActions: HeaderActions = { android: { startHeaderAction: { type: 'back', onPress: (t) => HybridAutoPlay.popTemplate() }, endHeaderActions: [ { type: 'image', image: { name: 'help', type: 'glyph' }, onPress: () => {} }, ], }, ios: { backButton: { type: 'back', onPress: (t) => HybridAutoPlay.popTemplate() }, trailingNavigationBarButtons: [ { type: 'image', image: { name: 'close', type: 'glyph' }, onPress: () => {} }, ], }, }; ``` ⚠️ **Do not pass a raw array of actions** to `headerActions` on Android for these templates. Arrays are only valid for **MapTemplate** header actions. ### For MapTemplate on Android: You can use the array format (1–4 actions) for the action strip. ```ts const mapHeaderActions: MapTemplateConfig['headerActions'] = { android: [ { type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }, { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => {} }, ], ios: { leadingNavigationBarButtons: [ { type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }, ], }, }; ``` ### Header action shapes overview: | Platform | Property | Shape | Limits / Notes | | --- | --- | --- | --- | | Android (header templates) | `headerActions.android` | `{ startHeaderAction?, endHeaderActions? }` | `endHeaderActions`: 1–2 buttons. `startHeaderAction` can be `appIcon`/`back`/custom. | | Android (MapTemplate) | `headerActions.android` | `ActionButton[]` | 1–4 action strip buttons. | | iOS | `headerActions.ios` | `{ backButton?, leadingNavigationBarButtons?, trailingNavigationBarButtons? }` | Each list supports 1–2 buttons. `backButton` optional (system back is added if omitted). | ### Actions & Button Types Quick Reference: - **Android header actions**: `startHeaderAction` + `endHeaderActions` (`AppButton | BackButton | ActionButton` for `startHeaderAction`, 1–2 buttons for `endHeaderActions`). If `headerActions` is omitted, Android renders the app icon automatically. - **iOS header actions**: `backButton` (optional), `leadingNavigationBarButtons` (1–2), `trailingNavigationBarButtons` (1–2). - **MapTemplate map buttons**: 1–4 buttons, including the special `pan` button. ``` -------------------------------- ### useSafeAreaInsets() Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Get safe area insets for any root component. ```APIDOC ## useSafeAreaInsets() ### Description Retrieves the safe area insets for the root component of your application. ### Usage ```javascript import { useSafeAreaInsets } from '@iternio/react-native-auto-play'; const insets = useSafeAreaInsets(); // insets object contains top, bottom, left, right values ``` ``` -------------------------------- ### MapTemplate Example Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Instantiate and set the MapTemplate as the root component. Supports map buttons and navigation APIs. ```typescript const map = new MapTemplate({ component: MapScreen, onStopNavigation: () => {}, headerActions: { android: [{ type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }] }, }); map.setRootTemplate(); ``` -------------------------------- ### Root Monorepo Commands Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Commands for linting, type-checking, building the core library, and running the example app on iOS and Android. ```bash yarn lint:auto-play # Lint the core library yarn typecheck:auto-play # Type-check the library yarn build:auto-play # Full library build yarn lint:example # Lint example app yarn typecheck:example # Type-check example app yarn ios # Run example app on iOS yarn android # Run example app on Android ``` -------------------------------- ### Start Voice Input Recording Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Start voice input recording. The recording stops automatically on silence or when maxDurationMs is reached. It resolves with a raw PCM ArrayBuffer. ```typescript // Start recording — resolves with a raw PCM ArrayBuffer (16 kHz, 16-bit, mono) // Recording stops automatically on silence or when maxDurationMs is reached const pcmBuffer = await HybridAutoPlay.startVoiceInput( 1500, // silenceThresholdMs (default 1500) 10_000, // maxDurationMs (default 10 000) 'Listening...' // text shown on the car screen while recording (iOS CarPlay) ); ``` -------------------------------- ### AppDelegate.swift MapTemplate Root View Setup Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Implement this method in your AppDelegate.swift to get the root view for MapTemplate, supporting both old and new React Native architectures. Adjust module names and properties as needed. ```swift @objc func getRootViewForAutoplay( moduleName: String, initialProperties: [String: Any]? ) -> UIView? { if RCTIsNewArchEnabled() { if let factory = reactNativeFactory?.rootViewFactory as? ExpoReactRootViewFactory { return factory.superView( withModuleName: moduleName, initialProperties: initialProperties, launchOptions: nil ) } return reactNativeFactory?.rootViewFactory.view( withModuleName: moduleName, initialProperties: initialProperties ) } if let rootView = window?.rootViewController?.view as? RCTRootView { return RCTRootView( bridge: rootView.bridge, moduleName: moduleName, initialProperties: initialProperties ) } return nil } ``` -------------------------------- ### Voice Input Recording Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md APIs for starting and stopping voice recording. ```APIDOC ## Voice Input Recording ### Description APIs to control the voice recording process, capturing audio from the microphone. ### Start Recording ```ts // Start recording — resolves with a raw PCM ArrayBuffer (16 kHz, 16-bit, mono) // Recording stops automatically on silence or when maxDurationMs is reached const pcmBuffer = await HybridAutoPlay.startVoiceInput( 1500, // silenceThresholdMs (default 1500) 10_000, // maxDurationMs (default 10 000) 'Listening...' // text shown on the car screen while recording (iOS CarPlay) ); ``` ### Stop Recording Early ```ts // Stop recording early — resolves startVoiceInput with the audio captured so far HibridAutoPlay.stopVoiceInput(); ``` ### Platform Specifics - **Android**: Uses `CarAudioRecord` when Android Auto is connected, otherwise falls back to standard `AudioRecord`. - **iOS**: Presents `CPVoiceControlTemplate` on the car screen when CarPlay is connected, and captures audio via `AVAudioEngine`. ``` -------------------------------- ### useMapTemplate() Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Get a reference to the parent `MapTemplate` instance. ```APIDOC ## useMapTemplate() ### Description Provides access to the parent `MapTemplate` instance. ### Usage ```javascript import { useMapTemplate } from '@iternio/react-native-auto-play'; const mapTemplate = useMapTemplate(); ``` ``` -------------------------------- ### Setup Android Auto Port Forwarding Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/apps/example/README.md This script is used to forward a port to the Android Auto Desktop Head Unit (DHU). Ensure the DHU is set up according to Android Developer documentation before running. ```bash ../../adb_port_setup.sh ``` -------------------------------- ### Register AutoPlay Components in App Entry Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Register your AutoPlay components and the headless task in your app's entry file (e.g., `index.js`). This setup is crucial for the library to function correctly when CarPlay or Android Auto is connected. ```javascript // index.js import { AppRegistry } from 'react-native'; import { name as appName } from './app.json'; import App from './src/App'; import registerAutoPlay from './src/AutoPlay'; // Your AutoPlay setup AppRegistry.registerComponent(appName, () => App); registerAutoPlay(); ``` -------------------------------- ### MapTemplateProvider Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Example of using the MapTemplateProvider context to access the current MapTemplate instance within a React component. ```typescript import { useMapTemplate } from "../contexts/MapTemplateProvider"; function MyMapComponent() { const mapTemplate = useMapTemplate(); // ... use mapTemplate ... } ``` -------------------------------- ### SafeAreaInsetsProvider Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Example of using the SafeAreaInsetsProvider context to access safe area insets within a React component. ```typescript import { useSafeAreaInsets } from "../contexts/SafeAreaInsetsProvider"; function MyComponent() { const insets = useSafeAreaInsets(); // ... use insets ... } ``` -------------------------------- ### Info.plist URL Types for Dashboard Button Launch Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Add this to your Info.plist to enable launching your CarPlay app from dashboard buttons. Replace the example URL scheme with your app's unique bundle identifier. ```xml CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLSchemes at.g4rb4g3.autoplay.example ``` -------------------------------- ### AutoPlay Configuration and Event Listeners Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md This snippet demonstrates how to set up the AutoPlay experience by registering components for the Dashboard and Cluster, and adding listeners for car connection and disconnection events. It also shows how to create and set a root template when a car connects. ```APIDOC ## AutoPlay Configuration and Event Listeners ### Description This section details the setup process for the AutoPlay feature in a React Native application. It includes registering components for the CarPlay Dashboard and AutoPlay Cluster, and managing car connection/disconnection events using listeners. When a car connects, a `MapTemplate` is created and set as the root template. ### Usage Call the `registerAutoPlay` function to initialize the AutoPlay experience. ```javascript // src/AutoPlay.tsx import { AutoPlayCluster, CarPlayDashboard, HybridAutoPlay, MapTemplate, useMapTemplate, } from '@iternio/react-native-auto-play'; import React, { useEffect } from 'react'; import { Platform, Text, View } from 'react-native'; // A simple component that can be reused across different screens const MyCarScreen = ({ title }: { title: string }) => ( {title} ); // The React component to be rendered inside the MapTemplate const MapScreen = () => { const mapTemplate = useMapTemplate(); useEffect(() => { // Show an alert on the car screen when the component mounts mapTemplate?.showAlert({ id: 'welcome-alert', title: { text: 'Welcome!' }, subtitle: { text: 'Your app is now running on the car screen.' }, durationMs: 5000, priority: 'low', }); }, [mapTemplate]); return ; }; const registerAutoPlay = () => { const onConnect = () => { // When a car is connected, create a MapTemplate and set it as the root const rootTemplate = new MapTemplate({ component: MapScreen, // Render our map component headerActions: { android: [ { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => console.log('Search pressed'), }, { type: 'image', image: { name: 'cog', type: 'glyph' }, onPress: () => console.log('Settings pressed'), }, ], ios: { leadingNavigationBarButtons: [ { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => console.log('Search pressed'), }, ], trailingNavigationBarButtons: [ { type: 'image', image: { name: 'cog', type: 'glyph' }, onPress: () => console.log('Settings pressed'), }, ], }, }, }); rootTemplate.setRootTemplate(); }; // Register components for the Dashboard and Cluster if (Platform.OS === 'ios') { CarPlayDashboard.setComponent(() => ); } AutoPlayCluster.setComponent(() => ); // Add listeners for car connection and disconnection events HybridAutoPlay.addListener('didConnect', onConnect); HybridAutoPlay.addListener('didDisconnect', () => { console.log('Car disconnected'); }); }; export default registerAutoPlay; ``` ### Core Types #### AutoText Most text props accept `AutoText` so you can localize and provide variants. You can pass either a string or an object with `text`/`variants` as used throughout the example app. #### AutoImage Images are provided as `AutoImage` objects with a `type` and `name`. The built-in icon set is Material Symbols (see **Icons**). You can also use bundled images from your native project. ### Template Configs (Props) Below is a concise overview of the most important props per template. Optional props are marked as **optional**. Required props are marked as **required**. ``` -------------------------------- ### Set Up Local Include Directories Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/android/CMakeLists.txt Configures the directories where the compiler should look for header files. ```cmake include_directories( "src/main/cpp" "../cpp" ) ``` -------------------------------- ### Run on Android Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/apps/example/README.md Execute this command to run the application on Android Auto after setting up port forwarding. ```bash yarn android ``` -------------------------------- ### Run on iOS Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/apps/example/README.md Execute this command to run the application on iOS. It can be tested on the iOS Simulator or with the CarPlay Simulator app. ```bash yarn ios ``` -------------------------------- ### Library Commands Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Commands for the react-native-autoplay library, including build, linting, type-checking, dependency analysis, spec generation, cleaning, and Swift formatting. ```bash yarn prepare # Full build: circular check → tsc → nitrogen → font bundling yarn lint # Biome check on src/ yarn lint-ci # Biome check with CI reporter yarn typecheck # tsc --noEmit yarn circular # Detect circular dependencies (dpdm) yarn specs # Re-generate Nitrogen specs yarn clean # Remove build artifacts yarn swift:format # Format Swift source files ``` -------------------------------- ### Apply react-native-config in build.gradle Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configure `android/app/build.gradle` to apply `react-native-config` and set `minSdkVersion` and `isAutomotiveApp` based on build flavors. ```groovy // android/app/build.gradle project.ext.envConfigFiles = [ automotive: ".env.automotive", // other flavors... ] apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" if (project.ext.has("env")) { rootProject.ext.minSdkVersion = project.ext.env.minSdkVersion rootProject.ext.isAutomotiveApp = project.ext.env.isAutomotiveApp } ``` -------------------------------- ### Define .env files for build variants Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Create separate `.env` files for different build variants, such as a default `.env` for Android Auto and `.env.automotive` for Android Automotive. ```dotenv # .env (for Android Auto) isAutomotiveApp=false minSdkVersion=24 ``` ```dotenv # .env.automotive minSdkVersion=29 isAutomotiveApp=true ``` -------------------------------- ### NitroModules TypeScript Interface Spec Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Example of a TypeScript interface spec used with NitroModules. These specs define the native module interfaces and are used to generate native code. ```typescript import { NitroModule } from "@margelo/nitro"; export interface AutoPlayModule extends NitroModule { // ... methods and properties ... } ``` -------------------------------- ### GridTemplate Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Information on using the GridTemplate for action grids. ```APIDOC ## GridTemplate ### Description Used for action grids. Supports `GridButton` items. ### Usage Refer to the library's examples for specific implementation details as no direct instantiation example is provided in the source. ``` -------------------------------- ### Info.plist Scene Manifest Configuration Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configure your Info.plist to support various CarPlay scene types like Dashboard, Instrument Cluster, and Head Unit. Adjust delegate class names as needed. ```xml UIApplicationSceneManifest CPSupportsDashboardNavigationScene CPSupportsInstrumentClusterNavigationScene UIApplicationSupportsMultipleScenes UISceneConfigurations CPTemplateApplicationDashboardSceneSessionRoleApplication UISceneClassName CPTemplateApplicationDashboardScene UISceneConfigurationName CarPlayDashboard UISceneDelegateClassName DashboardSceneDelegate CPTemplateApplicationInstrumentClusterSceneSessionRoleApplication UISceneClassName CPTemplateApplicationInstrumentClusterScene UISceneConfigurationName CarPlayCluster UISceneDelegateClassName ClusterSceneDelegate CPTemplateApplicationSceneSessionRoleApplication UISceneClassName CPTemplateApplicationScene UISceneConfigurationName CarPlayHeadUnit UISceneDelegateClassName HeadUnitSceneDelegate UIWindowSceneSessionRoleApplication UISceneClassName UIWindowScene UISceneConfigurationName WindowApplication UISceneDelegateClassName WindowApplicationSceneDelegate ``` -------------------------------- ### InformationTemplate Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Information on using the InformationTemplate for info panels. ```APIDOC ## InformationTemplate ### Description Used for info panels. Note that Android uses `PaneTemplate` while iOS uses `InformationTemplate`. ### Usage Refer to the library's examples for specific implementation details as no direct instantiation example is provided in the source. ``` -------------------------------- ### Link Libraries Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/android/CMakeLists.txt Links the main library with necessary system and Android core libraries. ```cmake target_link_libraries( ${PACKAGE_NAME} ${LOG_LIB} android # <-- Android core ) ``` -------------------------------- ### useVoiceInput() Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Reactively exposes the latest OS-triggered voice input (`location`, `query`). Android only. ```APIDOC ## useVoiceInput() ### Description Exposes OS-triggered voice input data reactively. This hook is Android-specific. For in-app recording, use `startVoiceInput` / `stopVoiceInput` directly. ### Usage ```javascript import { useVoiceInput } from '@iternio/react-native-auto-play'; const { location, query } = useVoiceInput(); ``` ``` -------------------------------- ### Configure Android Automotive Build Properties Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Set minimum SDK version and automotive app flag in `gradle.properties` for Android Automotive builds. The minimum `minSdkVersion` for Automotive is 29, and `isAutomotiveApp` should be `true`. ```properties # For Android Automotive minSdkVersion=29 isAutomotiveApp=true ``` -------------------------------- ### SignInTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Android-only configuration for a sign-in template, supporting QR, PIN, and input-based sign-in methods. ```APIDOC ## SignInTemplateConfig (Android-only) ### Description Android-only configuration for a sign-in template, supporting QR, PIN, and input-based sign-in methods. ### Properties - **`signInMethod`** (`SignInMethod`) - Required - The sign-in method configuration. Can be QRSignIn, PinSignIn, InputSignIn. - **`title`** (`string`) - Optional - Header title. - **`additionalText`** (`string`) - Optional - Additional descriptive text. - **`instructions`** (`string`) - Optional - Sign-in Instructions text. - **`actions`** (`ActionButton[]`) - Optional - Up to 2 buttons. - **`headerActions`** (`SignInHeaderActions`) - Optional - Header actions. ### SignInMethod - **QR** (`QrSignIn`) - QR Code sign in - **PIN** (`PinSignIn`) - PIN Code sign in (1–12 characters) - **Input** (`InputSignIn`) - Text sign in, for example mail/username and password For InputSignIn the keyboard and input fields can be configured with following properties: **KeyboardType enum:** `DEFAULT`, `EMAIL`, `PHONE`, `NUMBER` **TextInputType enum:** `PASSWORD`, `DEFAULT` ``` -------------------------------- ### Listen for OS-Triggered Voice Input (Android) Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Add a listener for OS-initiated voice actions on Android. This is a no-op on iOS. ```typescript const cleanup = HybridAutoPlay.addListenerVoiceInput((location, query) => { console.log('Voice query:', query, 'near', location); }); ``` -------------------------------- ### Voice Input Permission Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md APIs for managing voice input permissions. ```APIDOC ## Voice Input Permission ### Description APIs to check and request permission for using the device's microphone for voice input. ### Check Permission ```ts // Check whether permission is already granted const granted = HybridAutoPlay.hasVoiceInputPermission(); ``` ### Request Permission ```ts // Request permission if not yet granted const granted = await HybridAutoPlay.requestVoiceInputPermission(); ``` ``` -------------------------------- ### HybridAutoPlay Listeners Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md APIs for listening to connection state, render state, voice input, and safe area insets. ```APIDOC ## HybridAutoPlay Listeners ### `HybridAutoPlay.addListener(event, cb)` - **Description**: Listens for connection changes for the head unit. - **Parameters**: - `event` (string): `'didConnect'` or `'didDisconnect'` - `cb` (function): Callback function to execute on event. ### `HybridAutoPlay.addListenerRenderState(moduleName, cb)` - **Description**: Listens for render state changes for a specific module. - **Parameters**: - `moduleName` (string): The name of the module (e.g., `AutoPlayModules.*` or a cluster UUID). - `cb` (function): Callback function receiving `visibility` ('willAppear' | 'didAppear' | 'willDisappear' | 'didDisappear'). ### `HybridAutoPlay.addListenerVoiceInput(cb)` - **Description**: Listens for voice input events triggered by the OS (Android-only). Use `startVoiceInput` for in-app recording. - **Parameters**: - `cb` (function): Callback function receiving `location?` and `query?`. ### `HybridAutoPlay.addSafeAreaInsetsListener(moduleName, cb)` - **Description**: Listens for safe area inset changes for any module. - **Parameters**: - `moduleName` (string): The name of the module. - `cb` (function): Callback function receiving `insets`. ### Example Usage: ```ts import { AutoPlayModules, HybridAutoPlay } from '@iternio/react-native-auto-play'; const cleanup = HybridAutoPlay.addListener('didConnect', () => { console.log('Head unit connected'); }); const removeVisibility = HybridAutoPlay.addListenerRenderState( AutoPlayModules.AutoPlayRoot, (state) => console.log('AutoPlayRoot state', state) ); ``` ``` -------------------------------- ### Voice Input API Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Provides cross-platform in-app voice recording capabilities. ```APIDOC ## Voice Input API Provides cross-platform in-app voice recording capabilities. ### Methods - **`HybridAutoPlay.hasVoiceInputPermission()`** - Description: Synchronously checks microphone permission. - Platform: Both - **`HybridAutoPlay.requestVoiceInputPermission()`** - Description: Requests microphone permission. Behavior varies based on Android Auto connection and iOS version. - Platform: Both - **`HybridAutoPlay.startVoiceInput(silenceThresholdMs?, maxDurationMs?, listeningText?)`** - Description: Starts recording audio. Resolves with a raw PCM ArrayBuffer. - Parameters: - `silenceThresholdMs` (number, Optional) - The silence threshold in milliseconds. - `maxDurationMs` (number, Optional) - The maximum recording duration in milliseconds. - `listeningText` (string, Optional) - Text to display while listening. - Platform: Both (with platform-specific implementations for Android and iOS) - **`HybridAutoPlay.stopVoiceInput()`** - Description: Stops recording early and resolves the `startVoiceInput` promise with the audio captured so far. - Platform: Both - **`HybridAutoPlay.addListenerVoiceInput(cb)`** - Description: Android-only; fires when the OS triggers a voice action. No-op on iOS. - Parameters: - `cb` (function) - Callback function to handle voice actions. - Platform: Android ``` -------------------------------- ### Configure Header Actions for General Templates (Android/iOS) Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Use this structured object format for List, Grid, Information, Search, Message, and SignIn templates on Android to ensure proper header action rendering. iOS uses a similar structure for its navigation bar buttons. ```typescript const headerActions: HeaderActions = { android: { startHeaderAction: { type: 'back', onPress: (t) => HybridAutoPlay.popTemplate() }, endHeaderActions: [ { type: 'image', image: { name: 'help', type: 'glyph' }, onPress: () => {} }, ], }, ios: { backButton: { type: 'back', onPress: (t) => HybridAutoPlay.popTemplate() }, trailingNavigationBarButtons: [ { type: 'image', image: { name: 'close', type: 'glyph' }, onPress: () => {} }, ], }, }; ``` -------------------------------- ### Configure Header Actions for MapTemplate (Android/iOS) Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md For MapTemplate on Android, use an array format for the action strip (1-4 actions). iOS uses a similar structure for leading navigation bar buttons. ```typescript const mapHeaderActions: MapTemplateConfig['headerActions'] = { android: [ { type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }, { type: 'image', image: { name: 'search', type: 'glyph' }, onPress: () => {} }, ], ios: { leadingNavigationBarButtons: [ { type: 'image', image: { name: 'list', type: 'glyph' }, onPress: () => {} }, ], }, }; ``` -------------------------------- ### InformationTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration for an information template, including title, items, and actions. ```APIDOC ## InformationTemplateConfig ### Description Configuration for an information template, including title, items, and actions. ### Properties - **`title`** (`AutoText`) - Required - Header title. - **`items`** (`InformationItems`) - Optional - 1–4 rows. - **`actions`** (platform-specific) - Optional - Up to 2 buttons on Android, up to 3 on iOS. - **`headerActions`** (`HeaderActions`) - Optional - Header actions. - **`mapConfig`** (`BaseMapTemplateConfig`) - Optional - Android map-with-content layout. ``` -------------------------------- ### Find Log Library Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/android/CMakeLists.txt Locates the Android logging library. ```cmake find_library(LOG_LIB log) ``` -------------------------------- ### ListTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration for a list template, including title, sections, and header actions. ```APIDOC ## ListTemplateConfig ### Description Configuration for a list template, including title, sections, and header actions. ### Properties - **`title`** (`AutoText`) - Required - Header title. - **`sections`** (`Section`) - Optional - List sections/rows. Not providing anything here will result in a loading indicator on Android and an empty list on iOS. - **`headerActions`** (`HeaderActions`) - Optional - Header actions. - **`mapConfig`** (`BaseMapTemplateConfig`) - Optional - Android map-with-content layout. ``` -------------------------------- ### Listen for Compass and Speed Limit Changes on iOS Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Demonstrates how to listen for changes in compass and speed limit settings on iOS using AutoPlayCluster listeners. It includes setting up listeners and cleaning them up on component unmount. ```tsx // Listen for compass setting changes const compassCleanup = AutoPlayCluster.addListenerCompass((clusterId, isEnabled) => { console.log(`Compass is now ${isEnabled ? 'enabled' : 'disabled'} for cluster ${clusterId}`); }); // Listen for speed limit setting changes const speedLimitCleanup = AutoPlayCluster.addListenerSpeedLimit((clusterId, isEnabled) => { console.log(`Speed limit is now ${isEnabled ? 'enabled' : 'disabled'} for cluster ${clusterId}`); }); // Don't forget to clean up the listeners when your component unmounts useEffect(() => { return () => { compassCleanup(); speedLimitCleanup(); }; }, []); ``` -------------------------------- ### Define C++ Library and Sources Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/android/CMakeLists.txt Defines the main C++ shared library for the module and lists its source files. ```cmake add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp ) ``` -------------------------------- ### SearchTemplate Usage Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Information on using the SearchTemplate for search UI. ```APIDOC ## SearchTemplate ### Description Provides a search UI. Includes Android-only search bar callbacks. ### Usage Refer to the library's examples for specific implementation details as no direct instantiation example is provided in the source. ``` -------------------------------- ### GridTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration for a grid template, including title, buttons, and header actions. ```APIDOC ## GridTemplateConfig ### Description Configuration for a grid template, including title, buttons, and header actions. ### Properties - **`title`** (`AutoText`) - Required - Header title. - **`buttons`** (`GridButton[]`) - Required - Grid items. Providing an empty array will result in a loading indicator on Android and an empty template on iOS. - **`headerActions`** (`HeaderActions`) - Optional - Header actions. - **`mapConfig`** (`BaseMapTemplateConfig`) - Optional - Android map-with-content layout. ``` -------------------------------- ### Register CarPlayDashboard Buttons Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Use `setButtons` to make the CarPlay dashboard visible. This function requires an array of button configurations. ```typescript CarPlayDashboard.setButtons([ { titleVariants: ['Open App'], subtitleVariants: ['Dashboard shortcut'], image: { name: 'directions_car', type: 'glyph' }, onPress: () => console.log('open app'), }, ]); ``` -------------------------------- ### Request Voice Input Permission Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Request voice input permission if it has not yet been granted using HybridAutoPlay.requestVoiceInputPermission(). ```typescript // Request permission if not yet granted const granted = await HybridAutoPlay.requestVoiceInputPermission(); ``` -------------------------------- ### RootComponentInitialProps Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Props passed to every component registered with a template or scene, providing environment information. ```APIDOC ## Component Props #### RootComponentInitialProps Every component registered with a template (e.g., via `MapTemplate`'s `component` prop) or a scene (e.g., `CarPlayDashboard.setComponent`) receives `RootComponentInitialProps` as its props. This object contains important information about the environment where the component is being rendered. - `id`: A unique identifier for the screen. Can be `AutoPlayRoot` for the main screen, `CarPlayDashboard` for the dashboard, or a UUID for cluster displays. - `rootTag`: The React Native root tag for the view. - `colorScheme`: The initial color scheme (`'dark'` or `'light'`). Listen for changes with the `onAppearanceDidChange` event on the template. - `window`: An object containing the dimensions and scale of the screen: - `width`: The width of the screen. - `height`: The height of the screen. - `scale`: The screen's scale factor. **iOS Specific Properties:** On iOS, the component registered with `AutoPlayCluster.setComponent` receives additional props in its `RootComponentInitialProps` that indicate user preferences for the cluster display. You can also listen for changes to these settings. - `compass: boolean`: Indicates if the compass display is enabled by the user. The initial value is passed as a prop. - `speedLimit: boolean`: Indicates if the speed limit display is enabled by the user. The initial value is passed as a prop. You can listen for changes to these settings using listeners on the `AutoPlayCluster` object: ```tsx // Listen for compass setting changes const compassCleanup = AutoPlayCluster.addListenerCompass((clusterId, isEnabled) => { console.log(`Compass is now ${isEnabled ? 'enabled' : 'disabled'} for cluster ${clusterId}`); }); // Listen for speed limit setting changes const speedLimitCleanup = AutoPlayCluster.addListenerSpeedLimit((clusterId, isEnabled) => { console.log(`Speed limit is now ${isEnabled ? 'enabled' : 'disabled'} for cluster ${clusterId}`); }); // Don't forget to clean up the listeners when your component unmounts useEffect(() => { return () => { compassCleanup(); speedLimitCleanup(); }; }, []); ``` ``` -------------------------------- ### OS-triggered Voice Input (Android Only) Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Listens for voice input initiated by the operating system. ```APIDOC ## OS-triggered Voice Input (Android Only) ### Description Listens for voice input actions initiated by the operating system, such as "Hey Google, navigate to…". This is a no-op on iOS. ### Listener ```ts const cleanup = HybridAutoPlay.addListenerVoiceInput((location, query) => { console.log('Voice query:', query, 'near', location); }); ``` ### Cleanup Call the returned `cleanup` function to remove the listener. ``` -------------------------------- ### Register Headless Task Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Registering a headless task for the native side to invoke when a car connects. This task is responsible for initializing the JavaScript part of the app. ```typescript import { HybridAutoPlay } from "@react-native-auto-play/hybrid"; HypbridAutoPlay.registerHeadlessTask("myTaskName", () => { // ... initialize app and create templates ... }); ``` -------------------------------- ### Listen to Connection Events Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/CLAUDE.md Listening for car connection and disconnection events using HybridAutoPlay. This allows the app to react to the car's connection status. ```typescript import { HybridAutoPlay } from "@react-native-auto-play/hybrid"; HypbridAutoPlay.addListener('didConnect', () => { console.log('Car connected!'); }); HypbridAutoPlay.addListener('didDisconnect', () => { console.log('Car disconnected.'); }); ``` -------------------------------- ### Include Nitrogen Autolinking Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/android/CMakeLists.txt Includes the CMake script generated for autolinking Nitrogen dependencies. ```cmake include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake) ``` -------------------------------- ### MapTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration for rendering a map on the screen, including navigation events and UI elements. ```APIDOC ## MapTemplateConfig ### Description Configuration for rendering a map on the screen, including navigation events and UI elements. ### Properties - **`component`** (`React.ComponentType`) - Required - The React component to render on the map surface. - **`onStopNavigation`** (`(template: MapTemplate) => void`) - Required - Called when navigation is stopped by the system. - **`headerActions`** (`MapHeaderActions`) - Optional - Top action strip. - **`mapButtons`** (`MapButtons`) - Optional - 1–4 map buttons shown on the map. To get working gestures on the MapTemplate running on Android Auto you have to add a `MapPanButton`. - **`visibleTravelEstimate`** (`'first'` | `'last'`) - Optional - Which travel estimate to display. - **`onDidPan` / `onDidUpdateZoomGestureWithCenter`** (callbacks) - Optional - Map gesture events. - **`onAppearanceDidChange`** (`(colorScheme) => void`) - Optional - Listen for light/dark mode changes. - **`onAutoDriveEnabled`** (`(template) => void`) - Warning - Android-only auto drive callback. Make sure to take action when receiving this and simulate a drive to the set destination. [Check Android docs for details](https://developer.android.com/reference/androidx/car/app/navigation/NavigationManagerCallback#onAutoDriveEnabled()) ``` -------------------------------- ### Use Glyph Images by Name or Codepoint Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Render glyph images by specifying their type along with either their name or codepoint. This allows for flexible icon usage within the application. ```typescript { type: 'glyph', name: 'directions_car' } ``` ```typescript { type: 'glyph', codepoint: 0xe531 } ``` -------------------------------- ### SearchTemplateConfig Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Configuration for a search template, including title, results, and search-related callbacks. ```APIDOC ## SearchTemplateConfig ### Description Configuration for a search template, including title, results, and search-related callbacks. ### Properties - **`title`** (`AutoText`) - Required - Header title. - **`results`** (`SearchSection`) - Optional - Initial results. - **`headerActions`** (`HeaderActions`) - Optional - Header actions. - **`searchHint`** (`string`) - Optional - Android-only placeholder. - **`initialSearchText`** (`string`) - Optional - Android-only initial value. - **`onSearchTextChanged`** (`(text) => void`) - Required - Fired on text input changes. - **`onSearchTextSubmitted`** (`(text) => void`) - Required - Fired on submit. ``` -------------------------------- ### Template Lifecycle Callbacks Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Callbacks that can be passed to any template configuration for managing its lifecycle. ```APIDOC ## Template Lifecycle Callbacks All templates accept these lifecycle callbacks in their config: - `onWillAppear(animated?)` - `onDidAppear(animated?)` - `onWillDisappear(animated?)` - `onDidDisappear(animated?)` - `onPopped()` (not supported on all iOS templates, see notes in code) ### Example Usage: ```ts const template = new ListTemplate({ title: { text: 'Menu' }, onWillAppear: () => console.log('will appear'), onPopped: () => console.log('popped forever'), }); ``` ``` -------------------------------- ### Check Voice Input Permission Source: https://github.com/iternio-planning-ab/react-native-auto-play/blob/master/packages/react-native-autoplay/README.md Check whether voice input permission is already granted using HybridAutoPlay.hasVoiceInputPermission(). ```typescript // Check whether permission is already granted const granted = HybridAutoPlay.hasVoiceInputPermission(); ```