fix(audio): improve audio device state management

Add proper cleanup for both audio input manager and output supervisor when disabling audio
Ensure complete shutdown of audio processes before USB reconfiguration
This commit is contained in:
Alex P 2025-08-25 13:19:29 +00:00
parent 1a0377bbdf
commit 6f02870c90
1 changed files with 59 additions and 18 deletions

View File

@ -915,19 +915,40 @@ func rpcSetUsbDevices(usbDevices usbgadget.Devices) error {
// Handle audio process management if state is changing // Handle audio process management if state is changing
if previousAudioEnabled != newAudioEnabled { if previousAudioEnabled != newAudioEnabled {
if !newAudioEnabled && audioSupervisor != nil && audioSupervisor.IsRunning() { if !newAudioEnabled {
// Stop audio processes when audio is disabled // Stop audio processes when audio is disabled
logger.Info().Msg("stopping audio processes due to audio device being disabled") logger.Info().Msg("stopping audio processes due to audio device being disabled")
if err := audioSupervisor.Stop(); err != nil {
logger.Error().Err(err).Msg("failed to stop audio supervisor") // Stop audio input manager if active
} if currentSession != nil && currentSession.AudioInputManager != nil && currentSession.AudioInputManager.IsRunning() {
// Wait for audio processes to fully stop before proceeding logger.Info().Msg("stopping audio input manager")
for i := 0; i < 50; i++ { // Wait up to 5 seconds currentSession.AudioInputManager.Stop()
if !audioSupervisor.IsRunning() { // Wait for audio input to fully stop
break for i := 0; i < 50; i++ { // Wait up to 5 seconds
if !currentSession.AudioInputManager.IsRunning() {
break
}
time.Sleep(100 * time.Millisecond)
} }
time.Sleep(100 * time.Millisecond) logger.Info().Msg("audio input manager stopped")
} }
// Stop audio output supervisor
if audioSupervisor != nil && audioSupervisor.IsRunning() {
logger.Info().Msg("stopping audio output supervisor")
if err := audioSupervisor.Stop(); err != nil {
logger.Error().Err(err).Msg("failed to stop audio supervisor")
}
// Wait for audio processes to fully stop before proceeding
for i := 0; i < 50; i++ { // Wait up to 5 seconds
if !audioSupervisor.IsRunning() {
break
}
time.Sleep(100 * time.Millisecond)
}
logger.Info().Msg("audio output supervisor stopped")
}
logger.Info().Msg("audio processes stopped, proceeding with USB gadget reconfiguration") logger.Info().Msg("audio processes stopped, proceeding with USB gadget reconfiguration")
} else if newAudioEnabled && audioSupervisor != nil && !audioSupervisor.IsRunning() { } else if newAudioEnabled && audioSupervisor != nil && !audioSupervisor.IsRunning() {
// Start audio processes when audio is enabled (after USB reconfiguration) // Start audio processes when audio is enabled (after USB reconfiguration)
@ -980,18 +1001,38 @@ func rpcSetUsbDeviceState(device string, enabled bool) error {
config.UsbDevices.MassStorage = enabled config.UsbDevices.MassStorage = enabled
case "audio": case "audio":
// Handle audio process management // Handle audio process management
if !enabled && audioSupervisor != nil && audioSupervisor.IsRunning() { if !enabled {
// Stop audio processes when audio is disabled // Stop audio processes when audio is disabled
logger.Info().Msg("stopping audio processes due to audio device being disabled") logger.Info().Msg("stopping audio processes due to audio device being disabled")
if err := audioSupervisor.Stop(); err != nil {
logger.Error().Err(err).Msg("failed to stop audio supervisor") // Stop audio input manager if active
} if currentSession != nil && currentSession.AudioInputManager != nil && currentSession.AudioInputManager.IsRunning() {
// Wait for audio processes to fully stop logger.Info().Msg("stopping audio input manager")
for i := 0; i < 50; i++ { // Wait up to 5 seconds currentSession.AudioInputManager.Stop()
if !audioSupervisor.IsRunning() { // Wait for audio input to fully stop
break for i := 0; i < 50; i++ { // Wait up to 5 seconds
if !currentSession.AudioInputManager.IsRunning() {
break
}
time.Sleep(100 * time.Millisecond)
} }
time.Sleep(100 * time.Millisecond) logger.Info().Msg("audio input manager stopped")
}
// Stop audio output supervisor
if audioSupervisor != nil && audioSupervisor.IsRunning() {
logger.Info().Msg("stopping audio output supervisor")
if err := audioSupervisor.Stop(); err != nil {
logger.Error().Err(err).Msg("failed to stop audio supervisor")
}
// Wait for audio processes to fully stop
for i := 0; i < 50; i++ { // Wait up to 5 seconds
if !audioSupervisor.IsRunning() {
break
}
time.Sleep(100 * time.Millisecond)
}
logger.Info().Msg("audio output supervisor stopped")
} }
} else if enabled && audioSupervisor != nil { } else if enabled && audioSupervisor != nil {
// Ensure supervisor is fully stopped before starting // Ensure supervisor is fully stopped before starting