Carplay on Android head unit using onboard mfi chip or via CH341.
Kotlin
1,451
100 commits
updated Oct 10, 2026
An Android head-unit CarPlay receiver. It supports connecting to the MFi chip through a CH341 I2C bridge or directly through the board's I2C controller, and supports both wired and wireless CarPlay connections.
/dev/i2c-N devices, local certificate/private-key files, and Remote MFI
authentication (see the API below).More gestures to Settings page. Start with one finger in the upper quarter of the left eighth of the screen, slide down along that strip, and lift in the lower quarter.Save & Reconnect.Web displays, enable Main display and/or
Instrument display, set the resolution, then tap Save & Reconnect.https://<IP>:8080/main or /cluster, including
the access key; it can be copied).Use a recent Chrome, Edge, or Safari. If the browser cannot play H.265, turn
off HEVC (H.265) in Settings.
It works 👍. It has been tested on car head units and phones. If you encounter
an incompatible car head unit, please open an issue and attach your log from
/sdcard/Android/data/com.shilapi.xcertplay/files/logs/xcertplay.log.
Adapter board: CH341-to-MFI
Choose Local files under MFI certificate & signing target, then use the two
Choose buttons to select the certificate and private key with Android's system
document picker. The supported formats are a DER PKCS#7 certificate (.p7b)
and its matching, unencrypted DER PKCS#8 private key (.pk8). The app validates
that the files match before starting the phone connection and reloads them on
MFI reconnect.
Store the private key in a protected location. Neither file is copied into app preferences; only Android's persistent read permission and document URI are saved.
| Path | Purpose |
|---|---|
common/ | Shared CarPlay host activity, settings UI, persistence, and app resources used by both targets. |
mobile/ | Standard Android target using the shared CarPlay host UI. |
automotive/ | Android Automotive OS target with the shared host UI and advanced audio channel mapping. |
shared/ | Car App Library code plus the CH341, I2C, MFi, iPhone, iAP2, NCM, VPN, AirPlay, and media implementations. |
The Remote MFi client treats a remote service as an MFi chip for remote calls, or uses BAA authentication. Remote authentication avoids the process of connecting to a local MFi chip for authentication.
| Method | Path | Purpose | Request body | Success response | Failure response |
|---|---|---|---|---|---|
GET | /mfi/certificate | Get the MFi chip version, certificate type, and certificate contents; cached by the client after the first call | None | Certificate JSON | {"detail":"..."} |
POST | /mfi/sign | Sign the challenge | {"challenge":"...","requestId":"..."} | {"signature":"..."} | {"detail":"..."} |
POST | /mfi/reset | Request a reset of the remote MFi chip | {} | {"detail":""} | {"detail":"..."} |
(Optional) Standard Bearer Authentication can be used for verification.
Currently, only BAA Authentication has been tested.
28.2.13676358.On Windows PowerShell:
$env:JAVA_HOME = "C:\Program Files\Android\Android Studio\jbr"
.\gradlew.bat :shared:testDebugUnitTest :common:lintDebug :mobile:lintDebug :automotive:lintDebug :mobile:assembleDebug :automotive:assembleDebug
On macOS or Linux:
./gradlew :shared:testDebugUnitTest :common:lintDebug :mobile:lintDebug :automotive:lintDebug :mobile:assembleDebug :automotive:assembleDebug
Unsigned release APKs:
.\gradlew.bat :mobile:assembleRelease :automotive:assembleRelease
Thanks to LIVI for providing important reference for this project. Thanks to the showcase project for providing important reference for the BAA authentication in this project.
Licensed under the GNU General Public License v3.0.
511 followers · starred Oct 2026
4,602 followers · starred Sep 2026
1,709 followers · starred Sep 2026
178 followers · starred Sep 2026
Carplay on Android head unit using onboard mfi chip or via CH341.
Kotlin
1,451
100 commits
updated Oct 10, 2026
An Android head-unit CarPlay receiver. It supports connecting to the MFi chip through a CH341 I2C bridge or directly through the board's I2C controller, and supports both wired and wireless CarPlay connections.
/dev/i2c-N devices, local certificate/private-key files, and Remote MFI
authentication (see the API below).More gestures to Settings page. Start with one finger in the upper quarter of the left eighth of the screen, slide down along that strip, and lift in the lower quarter.Save & Reconnect.Web displays, enable Main display and/or
Instrument display, set the resolution, then tap Save & Reconnect.https://<IP>:8080/main or /cluster, including
the access key; it can be copied).Use a recent Chrome, Edge, or Safari. If the browser cannot play H.265, turn
off HEVC (H.265) in Settings.
It works 👍. It has been tested on car head units and phones. If you encounter
an incompatible car head unit, please open an issue and attach your log from
/sdcard/Android/data/com.shilapi.xcertplay/files/logs/xcertplay.log.
Adapter board: CH341-to-MFI
Choose Local files under MFI certificate & signing target, then use the two
Choose buttons to select the certificate and private key with Android's system
document picker. The supported formats are a DER PKCS#7 certificate (.p7b)
and its matching, unencrypted DER PKCS#8 private key (.pk8). The app validates
that the files match before starting the phone connection and reloads them on
MFI reconnect.
Store the private key in a protected location. Neither file is copied into app preferences; only Android's persistent read permission and document URI are saved.
| Path | Purpose |
|---|---|
common/ | Shared CarPlay host activity, settings UI, persistence, and app resources used by both targets. |
mobile/ | Standard Android target using the shared CarPlay host UI. |
automotive/ | Android Automotive OS target with the shared host UI and advanced audio channel mapping. |
shared/ | Car App Library code plus the CH341, I2C, MFi, iPhone, iAP2, NCM, VPN, AirPlay, and media implementations. |
The Remote MFi client treats a remote service as an MFi chip for remote calls, or uses BAA authentication. Remote authentication avoids the process of connecting to a local MFi chip for authentication.
| Method | Path | Purpose | Request body | Success response | Failure response |
|---|---|---|---|---|---|
GET | /mfi/certificate | Get the MFi chip version, certificate type, and certificate contents; cached by the client after the first call | None | Certificate JSON | {"detail":"..."} |
POST | /mfi/sign | Sign the challenge | {"challenge":"...","requestId":"..."} | {"signature":"..."} | {"detail":"..."} |
POST | /mfi/reset | Request a reset of the remote MFi chip | {} | {"detail":""} | {"detail":"..."} |
(Optional) Standard Bearer Authentication can be used for verification.
Currently, only BAA Authentication has been tested.
28.2.13676358.On Windows PowerShell:
$env:JAVA_HOME = "C:\Program Files\Android\Android Studio\jbr"
.\gradlew.bat :shared:testDebugUnitTest :common:lintDebug :mobile:lintDebug :automotive:lintDebug :mobile:assembleDebug :automotive:assembleDebug
On macOS or Linux:
./gradlew :shared:testDebugUnitTest :common:lintDebug :mobile:lintDebug :automotive:lintDebug :mobile:assembleDebug :automotive:assembleDebug
Unsigned release APKs:
.\gradlew.bat :mobile:assembleRelease :automotive:assembleRelease
Thanks to LIVI for providing important reference for this project. Thanks to the showcase project for providing important reference for the BAA authentication in this project.
Licensed under the GNU General Public License v3.0.
511 followers · starred Oct 2026
4,602 followers · starred Sep 2026
1,709 followers · starred Sep 2026
178 followers · starred Sep 2026