diff --git a/webrtc/modules/audio_device/audio_device_buffer.cc b/webrtc/modules/audio_device/audio_device_buffer.cc index 8227d5b077..905c69681f 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.cc +++ b/webrtc/modules/audio_device/audio_device_buffer.cc @@ -260,6 +260,12 @@ int32_t AudioDeviceBuffer::SetTypingStatus(bool typing_status) { return 0; } +void AudioDeviceBuffer::NativeAudioInterrupted() { + RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); + playout_thread_checker_.DetachFromThread(); + recording_thread_checker_.DetachFromThread(); +} + uint32_t AudioDeviceBuffer::NewMicLevel() const { RTC_DCHECK_RUN_ON(&recording_thread_checker_); return new_mic_level_; diff --git a/webrtc/modules/audio_device/audio_device_buffer.h b/webrtc/modules/audio_device/audio_device_buffer.h index 04e1be8687..2a5a84b22f 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.h +++ b/webrtc/modules/audio_device/audio_device_buffer.h @@ -118,6 +118,12 @@ class AudioDeviceBuffer { int32_t SetTypingStatus(bool typing_status); + // Called on iOS where the native audio layer can be interrupted by other + // audio applications. This method can then be used to reset internal + // states and detach thread checkers to allow for a new audio session where + // native callbacks may come from a new set of I/O threads. + void NativeAudioInterrupted(); + private: // Starts/stops periodic logging of audio stats. void StartPeriodicLogging(); diff --git a/webrtc/modules/audio_device/ios/audio_device_ios.mm b/webrtc/modules/audio_device/ios/audio_device_ios.mm index 1d59aff467..fb2f65d339 100644 --- a/webrtc/modules/audio_device/ios/audio_device_ios.mm +++ b/webrtc/modules/audio_device/ios/audio_device_ios.mm @@ -554,6 +554,15 @@ void AudioDeviceIOS::HandleInterruptionBegin() { RTCLog(@"Stopping the audio unit due to interruption begin."); if (!audio_unit_->Stop()) { RTCLogError(@"Failed to stop the audio unit for interruption begin."); + } else { + // The audio unit has been stopped but will be restarted when the + // interruption ends in HandleInterruptionEnd(). It will result in audio + // callbacks from a new native I/O thread which means that we must detach + // thread checkers here to be prepared for an upcoming new audio stream. + io_thread_checker_.DetachFromThread(); + // The audio device buffer must also be informed about the interrupted + // state so it can detach its thread checkers as well. + audio_device_buffer_->NativeAudioInterrupted(); } } is_interrupted_ = true;