Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Install the app on an Android device and open the displayed address in your car'
- **Background service**: Background operation and automatic connection.
- **Display and audio settings**: Adjustable display size, resolution, frame rate, and audio buffering.
- **CarPlay preferences**: Follow Android's day/night mode or force day/night; select Android/browser audio output and Android/browser/disabled microphone input. Preview custom 0–40% safe margins on each edge; microphone and safe-area changes reconnect the iPhone. Keep CarPlay when browsers go offline, or disconnect the iPhone after 1/5 minutes; browser reconnection cancels the timer.
- **Custom car branding**: In **Settings → OEM car name and icon**, rename CarPlay's return-to-car entry, select and crop a square image, or restore the default NIO name and icon. Changes apply on the next iPhone connection. Images are stored privately in the app, so the original file is no longer needed.
- **Location source**: **Settings → Location → Location source** defaults to the iPhone's own location, with no external location advertised or reported by WheelPlay. Select the Android device to provide its position when requested by the iPhone, after reconnecting and granting precise location permission. iOS and the navigation app determine location fusion; wireless connections on older Android versions can still require location permission.
- **Custom car branding**: In **Settings → Vehicle & location → OEM car name and icon**, rename CarPlay's return-to-car entry, select and crop a square image, or restore the default NIO name and icon. Changes apply on the next iPhone connection. Images are stored privately in the app, so the original file is no longer needed.
- **Location source**: **Settings → Vehicle & location → Location source** defaults to the iPhone's own location, with no external location advertised or reported by WheelPlay. Select the Android device to provide its position when requested by the iPhone, after reconnecting and granting precise location permission. iOS and the navigation app determine location fusion; wireless connections on older Android versions can still require location permission.
- **Diagnostic export**: Save diagnostic reports locally for troubleshooting.

## Getting started
Expand All @@ -33,15 +33,15 @@ Manage remembered browsers under Settings → 浏览器设备 (Browser devices)

Device memory is scoped to the current browser and origin (scheme, host and port). Clearing or disabling browser storage, switching HTTP / HTTPS, or changing the address requires fresh pairing. Android persists only hashes of random device secrets; the six-digit code is never stored as a remembered credential, and browser credentials are excluded from app backups.

For 60 fps, select WebRTC video passthrough under Settings → Display & Audio and set the negotiated frame rate to 60. Apply the settings and reconnect for the changes to take effect. Actual frame rate depends on the iPhone's output, network conditions, and browser decoding capabilities; static scenes may run at a lower frame rate. WebRTC uses local-network UDP without external STUN/TURN servers. It automatically falls back to JPEG if UDP is unavailable or the source video codec is incompatible. Allowing HEVC on the iPhone enables H.265 passthrough to browsers that support HEVC over WebRTC; H.264 is recommended for older browsers.
For 60 fps, select WebRTC video passthrough under Settings → Display & streaming and set the negotiated frame rate to 60. Apply the settings and reconnect for the changes to take effect. Actual frame rate depends on the iPhone's output, network conditions, and browser decoding capabilities; static scenes may run at a lower frame rate. WebRTC uses local-network UDP without external STUN/TURN servers. It automatically falls back to JPEG if UDP is unavailable or the source video codec is incompatible. Allowing HEVC on the iPhone enables H.265 passthrough to browsers that support HEVC over WebRTC; H.264 is recommended for older browsers.

The WebRTC interruption tolerance setting offers 4, 10 (default), or 30 seconds and applies on the next browser connection. Recoverable interruptions keep the last video frame visible while waiting for recovery; persistent problems fall back to JPEG after the grace period. Unsupported codecs and terminal connection failures still fall back immediately. This does not enlarge the video buffer or change control and audio connection rules. Refresh the webpage after updating the App. See the [stability and troubleshooting notes](docs/WEBRTC_RECOVERY.md) (Chinese).

If the video element renders incorrectly in your car's browser, enable “Use Canvas to display video (experimental)” on the webpage's connection screen before connecting. This is disabled by default. The selection is saved in the current browser and persists across automatic reconnects and page reloads; if browser storage is disabled, it applies only to the current page. WebRTC video is still decoded by an offscreen `<video>` element and drawn directly onto a visible Canvas with `drawImage()`. Video frame callbacks are preferred, with animation frames used for older browsers or when offscreen callbacks stall. Touch coordinates are mapped to the video's aspect ratio, and drawing failures trigger a fallback to JPEG. This mode may increase GPU / CPU usage. The video frame rate in the status bar still reflects the browser's video presentation statistics, not the actual Canvas drawing rate.

Canvas mode requires testing on car browsers such as NIO's. Changing the rendering path may help if an overlay covers only the native video element; it cannot guarantee success if the system stops decoding or overlays the entire page. Test while the vehicle is parked. Drivers should use only essential navigation interfaces while driving.

Select Audio output and Microphone source under Settings → Display & Audio. Output changes apply immediately; microphone source changes reconnect the iPhone. Disabling microphone input stops capture/uplink and removes input capability advertisements. Current routes are shown; unavailable browsers fall back to Android, while disabled microphone input blocks all fallback capture. Browser microphone input requires a trusted local HTTPS certificate, pairing through HTTPS, and granting microphone permission. See the [browser audio guide](docs/BROWSER_AUDIO.md) (Chinese). If trusted HTTPS or AudioWorklet is unavailable, use the Android microphone.
Select Audio output and Microphone source under Settings → Audio & microphone. Output changes apply immediately; microphone source changes reconnect the iPhone. Disabling microphone input stops capture/uplink and removes input capability advertisements. Current routes are shown; unavailable browsers fall back to Android, while disabled microphone input blocks all fallback capture. Browser microphone input requires a trusted local HTTPS certificate, pairing through HTTPS, and granting microphone permission. See the [browser audio guide](docs/BROWSER_AUDIO.md) (Chinese). If trusted HTTPS or AudioWorklet is unavailable, use the Android microphone.

## Requirements and limitations

Expand All @@ -52,7 +52,7 @@ Tesla compatibility helps car browsers that block private IP ranges reach the ph

Both methods clean up when disabled or when the Web service stops. Ordinary LAN Web listeners remain independent; optional HTTPS still requires a trusted certificate. See the [Tesla compatibility guide](docs/TESLA_HTTP.md) (Chinese).

Settings → Web listeners (Web 监听) contains the HTTP port (default `8080`), a self-managed Web hostname shared by HTTP and HTTPS, and an optional HTTPS switch. No Root access is required; listener ports range from `1024–65535`. Enabling HTTPS reveals its port (default `8443`) and inline certificate types: local default, PEM, and PKCS#12. Android's file picker imports PEM chains plus private keys (including encrypted keys) or PKCS#12 (`.p12` / `.pfx`) with passwords and key-alias selection. Identities are validated and saved in private non-backup storage; failed imports retain the current certificate, and occupied ports retain the current listener. Disabling HTTPS stops TLS while retaining its settings and certificate. See [Web listener and certificate setup](docs/BROWSER_AUDIO.md).
Settings → Web service (Web 服务) contains the HTTP port (default `8080`), a self-managed Web hostname shared by HTTP and HTTPS, and an optional HTTPS switch. No Root access is required; listener ports range from `1024–65535`. Enabling HTTPS reveals its port (default `8443`) and inline certificate types: local default, PEM, and PKCS#12. Android's file picker imports PEM chains plus private keys (including encrypted keys) or PKCS#12 (`.p12` / `.pfx`) with passwords and key-alias selection. Identities are validated and saved in private non-backup storage; failed imports retain the current certificate, and occupied ports retain the current listener. Disabling HTTPS stops TLS while retaining its settings and certificate. See [Web listener and certificate setup](docs/BROWSER_AUDIO.md).

- The server device requires Android 9 or later. The car's browser must support modern web features and touch interaction.
- The server device and car must be able to reach each other over the local network. Wireless connection compatibility depends on the devices' networking capabilities.
Expand All @@ -63,6 +63,8 @@ Settings → Web listeners (Web 监听) contains the HTTP port (default `8080`),

## Build

Android settings use Jetpack Compose. Category screens and shared controls live in `common/src/main/java/com/shilapi/xcertplay/settings/`; `SettingsViewModel` owns preferences and saved navigation state, while `DiPlayActivity` coordinates platform permissions, file pickers, and service changes. `SettingsScreen.kt` includes phone and large-text previews. Settings interaction tests use Compose semantics with Robolectric.

Use Android NDK 28.2.13676358 and CMake 3.22.1. The first build fetches pinned versions of libdatachannel and Mbed TLS from GitHub; subsequent builds reuse the local CMake cache. Run:

```sh
Expand Down
14 changes: 9 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ WheelPlay 是一款 Android 局域网 CarPlay 服务端应用,可将 iPhone
- **后台服务**:支持后台运行及自动连接。
- **显示与音频设置**:可调整画面尺寸、分辨率、帧率和音频缓冲。
- **CarPlay 使用偏好**:可选择跟随 Android/始终日间/始终夜间、Android/浏览器音频输出,以及 Android/浏览器/禁用麦克风。自定义四边 0–40% 安全区域,并预览布局;修改麦克风或安全区域会重新连接。浏览器离线策略可选保持连接或等待 1/5 分钟后断开 iPhone,重连浏览器会取消计时。
- **自定义车厂入口**:在「设置 → OEM 车厂名称与图标」修改 CarPlay「返回车机」入口的名称,选择图片并裁剪为正方形,或恢复默认 NIO 名称与图标;下次连接 iPhone 生效。图片保存在应用私有目录,无需保留原文件。
- **定位来源**:「设置 → 定位 → 定位来源」默认选择 iPhone 自身定位,此时 WheelPlay 不声明或上报外部定位。可选择 Android 设备定位,在下次连接并取得精确定位权限后,按 iPhone 请求提供设备位置。具体定位融合由 iOS 和导航 App 决定;旧版 Android 的无线连接仍可能需要定位权限。
- **自定义车厂入口**:在「设置 → 车厂与定位 → OEM 车厂名称与图标」修改 CarPlay「返回车机」入口的名称,选择图片并裁剪为正方形,或恢复默认 NIO 名称与图标;下次连接 iPhone 生效。图片保存在应用私有目录,无需保留原文件。
- **定位来源**:「设置 → 车厂与定位 → 定位来源」默认选择 iPhone 自身定位,此时 WheelPlay 不声明或上报外部定位。可选择 Android 设备定位,在下次连接并取得精确定位权限后,按 iPhone 请求提供设备位置。具体定位融合由 iOS 和导航 App 决定;旧版 Android 的无线连接仍可能需要定位权限。
- **诊断导出**:支持将诊断报告保存到本地,便于排查问题。

设置首页提供九个分类入口:iPhone 连接、画面与串流、音频与麦克风、车厂与定位、浏览器设备、Web 服务、Tesla 兼容、CarPlay 认证资源、帮助与关于。点击进入二级页,顶部返回按钮或系统返回键回到分类首页;切换底部标签和旋转屏幕后保留当前分类及滚动位置。

## 使用方式

1. 在 Android 服务设备上安装并启动 WheelPlay。
Expand All @@ -33,15 +35,15 @@ WheelPlay 是一款 Android 局域网 CarPlay 服务端应用,可将 iPhone

设备记忆保存于当前浏览器及访问地址(协议、主机、端口)的本地存储;清理浏览器数据、禁用存储、切换 HTTP / HTTPS 或访问地址后需要重新配对。Android 仅持久保存随机设备密钥的哈希,凭据不包含六位配对码,也不进入应用备份。

追求 60 fps 时,在「设置 → 画面与音频」选择 WebRTC 视频直通,并将协商帧率设为 60;应用设置并重新连接后生效。实际帧率取决于 iPhone 输出、网络和浏览器解码能力,静态画面可能降低帧率。WebRTC 使用局域网 UDP,不依赖外部 STUN/TURN;UDP 不通或源视频编码不兼容时自动回退 JPEG。允许 iPhone 使用 HEVC 后,可向支持 HEVC / WebRTC 的浏览器直通 H.265;较旧浏览器建议保持 H.264。
追求 60 fps 时,在「设置 → 画面与串流」选择 WebRTC 视频直通,并将协商帧率设为 60;应用设置并重新连接后生效。实际帧率取决于 iPhone 输出、网络和浏览器解码能力,静态画面可能降低帧率。WebRTC 使用局域网 UDP,不依赖外部 STUN/TURN;UDP 不通或源视频编码不兼容时自动回退 JPEG。允许 iPhone 使用 HEVC 后,可向支持 HEVC / WebRTC 的浏览器直通 H.265;较旧浏览器建议保持 H.264。

「WebRTC 卡顿容忍时间」可选 4 秒、10 秒(默认)或 30 秒,下次浏览器连接生效。短暂断流时保留最后一帧并等待恢复,持续异常超过阈值才回退 JPEG;不支持的编码或彻底失败的连接仍立即回退。该设置不会扩大视频缓冲,控制与音频保持各自的连接规则。更新 App 后请刷新网页。详见 [稳定性分析与排查](docs/WEBRTC_RECOVERY.md)。

车机浏览器的视频元素显示异常时,可在网页连接界面勾选「使用 Canvas 显示视频(实验性)」,再连接设备。默认关闭;选择保存在当前浏览器,自动重连及刷新后保留(浏览器禁用存储时仅当前页面有效)。WebRTC 视频仍由 `<video>` 解码,元素放在屏幕外,使用 `drawImage()` 直接绘制到可见 Canvas;优先使用视频帧回调,旧浏览器或离屏回调停顿时使用动画帧刷新。触控区域按画面比例映射,绘制失败自动回退 JPEG。该模式可能增加 GPU / CPU 消耗;状态栏中的视频帧率仍为浏览器的视频呈现统计,不能代表 Canvas 的实际绘制帧率。

Canvas 模式需要蔚来等车机实测:若遮罩只覆盖原生视频元素,改变显示路径可能有效;若系统停止解码或在整个页面上叠加遮罩,则无法保证有效。请在车辆停稳后验证,驾驶员行驶中只应使用必要的导航界面。

在 App「设置 → 画面与音频」选择「音频输出」和「麦克风来源」。音频输出即时切换;麦克风来源修改后重新连接,禁用时停止采集与上传并取消输入能力声明。页面显示当前路由,浏览器未就绪时回退 Android;禁用麦克风时始终禁止回退采集。浏览器麦克风需要先配置该设备的本地 HTTPS 证书,再从 HTTPS 入口重新配对并授权;步骤见 [浏览器音频说明](docs/BROWSER_AUDIO.md)。若车机浏览器不支持可信 HTTPS 或 AudioWorklet,继续使用 Android 麦克风。
在 App「设置 → 音频与麦克风」选择「音频输出」和「麦克风来源」。音频输出即时切换;麦克风来源修改后重新连接,禁用时停止采集与上传并取消输入能力声明。页面显示当前路由,浏览器未就绪时回退 Android;禁用麦克风时始终禁止回退采集。浏览器麦克风需要先配置该设备的本地 HTTPS 证书,再从 HTTPS 入口重新配对并授权;步骤见 [浏览器音频说明](docs/BROWSER_AUDIO.md)。若车机浏览器不支持可信 HTTPS 或 AudioWorklet,继续使用 Android 麦克风。

## 使用要求与限制

Expand All @@ -54,7 +56,7 @@ Canvas 模式需要蔚来等车机实测:若遮罩只覆盖原生视频元素

## Web 监听配置

「设置 → Web 监听」集中配置 HTTP 端口(默认 `8080`)、HTTP / HTTPS 共用的自备 Web 域名和可选 HTTPS,无需 Root。实际监听端口范围为 `1024–65535`;打开 HTTPS 后显示 Web HTTPS 端口(默认 `8443`)及页面内的证书类型选择器:默认本地证书、PEM、PKCS#12。系统文件选择器支持 PEM 证书链+私钥(含加密私钥),或 PKCS#12(`.p12` / `.pfx`,可选择私钥条目)。导入前验证证书与私钥,保存到 App 私有且不备份的存储;失败保留当前证书,端口绑定失败保留原监听器。关闭 HTTPS 仅停止 TLS 监听,保留配置与证书。详见 [Web 监听与证书说明](docs/BROWSER_AUDIO.md)。
「设置 → Web 服务」集中配置 HTTP 端口(默认 `8080`)、HTTP / HTTPS 共用的自备 Web 域名和可选 HTTPS,无需 Root。实际监听端口范围为 `1024–65535`;打开 HTTPS 后显示 Web HTTPS 端口(默认 `8443`)及页面内的证书类型选择器:默认本地证书、PEM、PKCS#12。系统文件选择器支持 PEM 证书链+私钥(含加密私钥),或 PKCS#12(`.p12` / `.pfx`,可选择私钥条目)。导入前验证证书与私钥,保存到 App 私有且不备份的存储;失败保留当前证书,端口绑定失败保留原监听器。关闭 HTTPS 仅停止 TLS 监听,保留配置与证书。详见 [Web 监听与证书说明](docs/BROWSER_AUDIO.md)。

## Tesla 兼容模式(实验)

Expand All @@ -69,6 +71,8 @@ Canvas 模式需要蔚来等车机实测:若遮罩只覆盖原生视频元素

## 构建

Android 设置界面使用 Jetpack Compose。分类页面与共用控件位于 `common/src/main/java/com/shilapi/xcertplay/settings/`;`SettingsViewModel` 管理偏好与可恢复的导航状态,`DiPlayActivity` 协调系统权限、文件选择和服务操作。`SettingsScreen.kt` 提供手机及大字体预览,设置交互测试通过 Robolectric 和 Compose 语义节点执行。

使用 Android NDK 28.2.13676358 和 CMake 3.22.1。首次构建会从 GitHub 获取固定版本的 libdatachannel 及 Mbed TLS;后续复用本地 CMake 缓存。运行 `./gradlew :mobile:assembleDebug`。

源码构建默认不包含 CarPlay 认证资源。未配置有效资源时不会启动 Web 服务或 CarPlay;导入校验通过后自动启动 Web 服务。包内自带有效资源的安装包可直接使用,仍允许用户导入替换,且用户资源优先。在 **设置 → CarPlay 认证资源** 中手动选择 `identity.pk8` 和 `certificate.p7b`,或通过下载入口获取 DiPlay 官网 APK,再选择“从 DiPlay APK 导入”;也可在文件管理器中将该 APK 分享给 WheelPlay,无需安装 DiPlay。导入在本机完成,校验私钥与证书匹配后才替换原有资源;资源保存在应用私有目录,不上传、不参与备份。详见 [认证资源导入说明](docs/AUTHENTICATION_IMPORT.md)。
Expand Down
Loading
Loading