feat(android): native display resolution + Settings screen
The connect mode was hardcoded to 720p60 — violating the "native client resolution, no scaling" invariant. Derive the device's real display mode (landscape, long edge = width) and add a Settings screen to tune the stream, mirroring the Linux/Apple clients. - crates/punktfunk-android: nativeConnect gains bitrateKbps + compositorPref + gamepadPref (CompositorPref/GamepadPref wire bytes via from_u8); these were hardcoded Auto/Auto/0. - app/Settings.kt: Settings (width/height/hz/bitrate/compositor/gamepad; 0 = native/auto) + a SharedPreferences store + nativeDisplayMode (Display.mode, landscape-swapped) + effectiveMode + the UI option tables. - app/SettingsScreen.kt: dropdowns for resolution / refresh / bitrate / compositor / controller. - MainActivity: App owns the settings + a Settings screen; ConnectScreen resolves the effective mode (Native = the display), shows it on the Connect button, and threads the prefs through nativeConnect. Mic + codec selection deferred (mic uplink isn't wired yet; the decoder is HEVC-only). Verified live (emulator pf_phone -> home-worker-2): default -> host mode=2400x1080@60 (the emulator's native display, was 720p); Settings 1920x1080 + 20 Mbps + DualSense -> host mode=1920x1080, requested_kbps=20000, gamepad=dualsense (host created a UHID DualSense). Settings persist across screens; pinned reconnect stays silent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,10 @@ object NativeBridge {
|
||||
/**
|
||||
* Connect, presenting [certPem]/[keyPem] (both empty = anonymous) and pinning [pinHex] (empty =
|
||||
* trust-on-first-use — read [nativeHostFingerprint] after; else 64-hex host SHA-256, mismatch →
|
||||
* `0`). Returns an opaque session handle, or `0` on failure. Pair with exactly one [nativeClose].
|
||||
* `0`). [width]/[height]/[refreshHz] are the requested virtual-output mode (the host streams at
|
||||
* exactly this); [bitrateKbps] 0 = host default; [compositorPref]/[gamepadPref] are the
|
||||
* `CompositorPref`/`GamepadPref` wire bytes (0 = Auto). Returns an opaque session handle, or `0`
|
||||
* on failure. Pair with exactly one [nativeClose].
|
||||
*/
|
||||
external fun nativeConnect(
|
||||
host: String,
|
||||
@@ -38,6 +41,9 @@ object NativeBridge {
|
||||
certPem: String,
|
||||
keyPem: String,
|
||||
pinHex: String,
|
||||
bitrateKbps: Int,
|
||||
compositorPref: Int,
|
||||
gamepadPref: Int,
|
||||
): Long
|
||||
|
||||
/** 64-hex SHA-256 of the cert the host presented on [handle]; valid after a successful connect. */
|
||||
|
||||
Reference in New Issue
Block a user