fix(android): recover from input stream failures
This commit is contained in:
@@ -421,7 +421,7 @@ impl AndroidVoiceUnit {
|
||||
let input_builder = input_builder.set_callback(input_cb);
|
||||
|
||||
let mut input_stream = match input_builder.open_stream() {
|
||||
Ok(s) => s,
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
// Input-preset fallback ladder (SDD-112 item 6) X
|
||||
// Sharing-mode ladder (SDD-112 item 7), explored
|
||||
@@ -432,14 +432,36 @@ impl AndroidVoiceUnit {
|
||||
error = ?e,
|
||||
"android: primary input stream open failed; entering fallback ladder"
|
||||
);
|
||||
Self::open_input_fallback(cfg, &event_tx, capture_state.clone())?
|
||||
match Self::open_input_fallback(cfg, &event_tx, capture_state.clone()) {
|
||||
Ok(s) => Some(s),
|
||||
Err(fallback_err) => {
|
||||
warn!(
|
||||
target: "chanora_audio",
|
||||
error = %fallback_err,
|
||||
"android: input unavailable after all fallbacks; continuing listen-only with output stream"
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let input_perf = perf_from_oboe(input_stream.get_performance_mode());
|
||||
let input_share = share_from_oboe(input_stream.get_sharing_mode());
|
||||
let input_sample_rate = input_stream.get_sample_rate();
|
||||
let input_frames_per_burst = input_stream.get_frames_per_burst();
|
||||
let input_perf = input_stream
|
||||
.as_ref()
|
||||
.map(|s| perf_from_oboe(s.get_performance_mode()))
|
||||
.unwrap_or(AchievedPerformanceMode::None);
|
||||
let input_share = input_stream
|
||||
.as_ref()
|
||||
.map(|s| share_from_oboe(s.get_sharing_mode()))
|
||||
.unwrap_or(AchievedSharingMode::Shared);
|
||||
let input_sample_rate = input_stream
|
||||
.as_ref()
|
||||
.map(|s| s.get_sample_rate())
|
||||
.unwrap_or(0);
|
||||
let input_frames_per_burst = input_stream
|
||||
.as_mut()
|
||||
.map(|s| s.get_frames_per_burst())
|
||||
.unwrap_or(0);
|
||||
let session_id = None;
|
||||
warn!(
|
||||
target: "chanora_audio",
|
||||
@@ -570,7 +592,7 @@ impl AndroidVoiceUnit {
|
||||
publish_android_audio_diagnostics(diagnostics);
|
||||
|
||||
Ok(Self {
|
||||
input: Some(input_stream),
|
||||
input: input_stream,
|
||||
output: Some(output_stream),
|
||||
input_perf,
|
||||
input_share,
|
||||
@@ -697,8 +719,14 @@ impl AndroidVoiceUnit {
|
||||
impl MobileVoiceAudioBackend for AndroidVoiceUnit {
|
||||
fn start(&mut self) -> Result<(), BackendError> {
|
||||
if let Some(s) = self.input.as_mut() {
|
||||
s.start()
|
||||
.map_err(|e| BackendError::LifecycleFailed(format!("input start: {e:?}")))?;
|
||||
if let Err(e) = s.start() {
|
||||
warn!(
|
||||
target: "chanora_audio",
|
||||
error = ?e,
|
||||
"android: input start failed; continuing listen-only with output stream"
|
||||
);
|
||||
self.input = None;
|
||||
}
|
||||
}
|
||||
if let Some(s) = self.output.as_mut() {
|
||||
s.start()
|
||||
|
||||
@@ -459,10 +459,18 @@ pub async fn connect(
|
||||
identity: None,
|
||||
ready_timeout: Duration::from_secs(15),
|
||||
};
|
||||
let snap = runtime()
|
||||
let snap = match runtime()
|
||||
.spawn(async move { session().connect(cfg).await })
|
||||
.await
|
||||
.map_err(|e| task_join_error("connect", e))??;
|
||||
.map_err(|e| task_join_error("connect", e))?
|
||||
{
|
||||
Ok(snap) => snap,
|
||||
Err(chanora_core::CoreError::AlreadyConnected) => runtime()
|
||||
.spawn(async { session().snapshot().await })
|
||||
.await
|
||||
.map_err(|e| task_join_error("connect.snapshot", e))??,
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
Ok(snap.into())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user