Skip to content

Commit e30b448

Browse files
committed
fix(deeplink): prevent deadlock in pause/resume actions
1 parent d9721fa commit e30b448

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

apps/desktop/src-tauri/src/deeplink_actions.rs

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,27 +162,76 @@ impl DeepLinkAction {
162162
}
163163
DeepLinkAction::PauseRecording => {
164164
let state = app.state::<ArcLock<App>>();
165-
let guard = state.read().await;
166-
if let Some(recording) = guard.current_recording() {
167-
recording.pause().await.map_err(|e| e.to_string())
168-
} else {
169-
Ok(())
165+
let (instant_handle, studio_handle) = {
166+
let guard = state.read().await;
167+
match guard.current_recording() {
168+
Some(crate::recording::InProgressRecording::Instant { handle, .. }) => {
169+
(Some(handle.clone()), None)
170+
}
171+
Some(crate::recording::InProgressRecording::Studio { handle, .. }) => {
172+
(None, Some(handle.clone()))
173+
}
174+
None => (None, None),
175+
}
176+
};
177+
178+
if let Some(handle) = instant_handle {
179+
handle.pause().await.map_err(|e| e.to_string())?;
180+
}
181+
if let Some(handle) = studio_handle {
182+
handle.pause().await.map_err(|e| e.to_string())?;
170183
}
184+
Ok(())
171185
}
172186
DeepLinkAction::ResumeRecording => {
173187
let state = app.state::<ArcLock<App>>();
174-
let guard = state.read().await;
175-
if let Some(recording) = guard.current_recording() {
176-
recording.resume().await.map_err(|e| e.to_string())
177-
} else {
178-
Ok(())
188+
let (instant_handle, studio_handle) = {
189+
let guard = state.read().await;
190+
match guard.current_recording() {
191+
Some(crate::recording::InProgressRecording::Instant { handle, .. }) => {
192+
(Some(handle.clone()), None)
193+
}
194+
Some(crate::recording::InProgressRecording::Studio { handle, .. }) => {
195+
(None, Some(handle.clone()))
196+
}
197+
None => (None, None),
198+
}
199+
};
200+
201+
if let Some(handle) = instant_handle {
202+
handle.resume().await.map_err(|e| e.to_string())?;
179203
}
204+
if let Some(handle) = studio_handle {
205+
handle.resume().await.map_err(|e| e.to_string())?;
206+
}
207+
Ok(())
180208
}
181209
DeepLinkAction::SwitchMicrophone { mic_label } => {
210+
if let Some(ref label) = mic_label {
211+
let available_mics = cap_recording::feeds::microphone::MicrophoneFeed::list();
212+
if !available_mics.contains_key(label) {
213+
return Err(format!("Microphone with label \"{}\" not found", label));
214+
}
215+
}
216+
182217
let state = app.state::<ArcLock<App>>();
183218
crate::set_mic_input(state, mic_label).await
184219
}
185220
DeepLinkAction::SwitchCamera { camera } => {
221+
if let Some(ref id) = camera {
222+
let cameras: Vec<_> = cap_camera::list_cameras().collect();
223+
let exists = cameras.iter().any(|info| match id {
224+
DeviceOrModelID::DeviceID(device_id) => info.device_id() == device_id,
225+
DeviceOrModelID::ModelID(model_id) => {
226+
info.model_id().is_some_and(|existing| existing == model_id)
227+
}
228+
});
229+
230+
if !exists {
231+
return Err(format!("Camera with ID \"{:?}\" not found", id));
232+
}
233+
}
234+
186235
let state = app.state::<ArcLock<App>>();
187236
crate::set_camera_input(app.clone(), state, camera).await
188237
}

0 commit comments

Comments
 (0)