fix(core,bridge,ios): voice_join survives audio-engine failure; iOS log file
User report from iPhone: 'mute / continuous / PTT buttons missing'
with NO error popup. Root cause: voice_join's audio-engine startup
was failing silently, and the failure propagated out as a hard
error \u2014 which means SessionEvent::VoiceState(true) was never sent
to Dart even though the server-side channel move had already
succeeded. Dart's _inChannel stayed false; every control gated on
_inChannel disappeared while the channel tree continued to show
the user as joined.
This commit makes voice_join lenient on audio-engine failures so
the UI state matches the server-side reality, and also gives iOS
a writable log file so diagnostics from device builds are
recoverable for the first time.
core/chanora_core/src/lib.rs::voice_join
* ensure_audio_running's error is now logged + emitted as
SessionEvent::AudioStopped, but does NOT abort voice_join.
The server move at step 1 already succeeded; failing the
Dart-visible promise here would leave the UI in a phantom
'in-channel visually but no controls' state. After this
commit:
- mic / headset / settings appear in the AppBar
- PTT button appears at the bottom
- status chip shows live audio state ('Mic on/off')
- if audio actually failed (mic permission denied,
no input device, CoreAudio rejecting stream config)
the user can retry by switching modes / channels;
BridgeEvent::AudioStopped wires _audioStarted=false
in Dart so audio-stats poll is honest about the
engine state.
crates/chanora_bridge/src/api.rs::log_file_path
* iOS now writes the log to /home/milkice/Documents/chanora.log
(Documents is the standard user-visible iOS sandbox dir).
* Android remains None pending the bridge JNI init wiring
a writable path (P1 follow-up).
apps/chanora_flutter/ios/Runner/Info.plist
* Adds UIFileSharingEnabled + LSSupportsOpeningDocumentsInPlace
so the Documents directory shows up under 'On My iPhone \u2192
Chanora' in the Files.app. The user can now copy chanora.log
out for support without needing Xcode \u2192 Devices and
Simulators \u2192 Download Container.
Workspace tests: 78/0/1 unchanged.
flutter build ios --release --no-codesign: 22.7 s clean
(Runner.app 29.9 MB).
This commit is contained in:
@@ -918,8 +918,36 @@ impl ChanoraSession {
|
||||
self.emit_voice_state(false).await;
|
||||
return Err(e);
|
||||
}
|
||||
// 2. Bring the audio engine up.
|
||||
self.ensure_audio_running().await?;
|
||||
// 2. Bring the audio engine up. Tolerate failure: the
|
||||
// server-side channel move has ALREADY succeeded (step
|
||||
// 1), so the user is in the channel from every other
|
||||
// peer's perspective. Failing voice_join hard here would
|
||||
// leave the UI in a phantom "you're in the channel
|
||||
// visually but no controls" state because the calling
|
||||
// Dart code wouldn't receive the VoiceState(true) event
|
||||
// that gates the AppBar mute icons + the on-screen PTT
|
||||
// button. Honest behaviour: surface the audio error
|
||||
// once on the event channel (via the AudioStopped event
|
||||
// consumers already handle), then continue so the UI
|
||||
// matches reality — user is in the channel, but mic /
|
||||
// speakers may be silent until they resolve the audio
|
||||
// error (e.g. grant mic permission, plug in a working
|
||||
// device).
|
||||
if let Err(audio_err) = self.ensure_audio_running().await {
|
||||
warn!(
|
||||
target: "chanora_core",
|
||||
error = %audio_err,
|
||||
channel_id,
|
||||
"voice_join: server move succeeded but audio engine \
|
||||
failed to start; continuing with no-audio in-channel \
|
||||
state so the UI matches the server-side state"
|
||||
);
|
||||
// Tell subscribers the audio engine is not running so
|
||||
// any audio-stats poll / level meter renders correctly.
|
||||
// The voice_join itself still resolves Ok below so the
|
||||
// UI gains the channel + mute + PTT controls.
|
||||
let _ = self.events_tx.send(SessionEvent::AudioStopped);
|
||||
}
|
||||
// 3. Belt-and-braces: if the server replied Ok but never
|
||||
// actually moved us (legacy server, command processed
|
||||
// but rolled back later, etc.) the snapshot poll catches
|
||||
|
||||
Reference in New Issue
Block a user