Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <Foundation/Foundation.h>
#include <IOKit/audio/IOAudioTypes.h>

#include <exception>

#if !defined(MAC_OS_VERSION_12_0) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0
#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster
#endif
Expand Down Expand Up @@ -388,28 +390,40 @@ namespace jni
OSStatus CoreAudioDeviceManager::deviceListenerProc(AudioObjectID objectID, UInt32 numberAddresses, const AudioObjectPropertyAddress addresses[], void * clientData) {
CoreAudioDeviceManager * manager = static_cast<CoreAudioDeviceManager *>(clientData);

// This runs on a CoreAudio HAL queue. An exception that leaves it has no handler above
// it and terminates the process, so nothing thrown below may escape: a device that
// vanishes between the device list and the read of its properties is an ordinary event
// (Bluetooth profile switch, an aggregate device torn down), not a fatal one.
for (int i = 0; i < numberAddresses; i++) {
switch (addresses[i].mSelector) {
case kAudioHardwarePropertyDevices:
{
manager->onDevicesChanged();
break;
}
try {
switch (addresses[i].mSelector) {
case kAudioHardwarePropertyDevices:
{
manager->onDevicesChanged();
break;
}

case kAudioHardwarePropertyDefaultInputDevice:
{
AudioDevicePtr def = manager->getDefaultCaptureDevice();
manager->onDefaultDeviceChanged(kAudioObjectPropertyScopeInput, manager->captureDevices, def);
break;
}
case kAudioHardwarePropertyDefaultInputDevice:
{
AudioDevicePtr def = manager->getDefaultCaptureDevice();
manager->onDefaultDeviceChanged(kAudioObjectPropertyScopeInput, manager->captureDevices, def);
break;
}

case kAudioHardwarePropertyDefaultOutputDevice:
{
AudioDevicePtr defp = manager->getDefaultPlaybackDevice();
manager->onDefaultDeviceChanged(kAudioObjectPropertyScopeOutput, manager->playbackDevices, defp);
break;
case kAudioHardwarePropertyDefaultOutputDevice:
{
AudioDevicePtr defp = manager->getDefaultPlaybackDevice();
manager->onDefaultDeviceChanged(kAudioObjectPropertyScopeOutput, manager->playbackDevices, defp);
break;
}
}
}
catch (const std::exception & e) {
RTC_LOG(LS_ERROR) << "CoreAudio: Device change handling failed: " << e.what();
}
catch (...) {
RTC_LOG(LS_ERROR) << "CoreAudio: Device change handling failed";
}
}

return noErr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "modules/audio_device/include/audio_device.h"
#include "rtc_base/logging.h"

#include <exception>
#include <stdlib.h>

namespace jni
Expand Down Expand Up @@ -408,7 +409,17 @@ namespace jni
{
RTC_LOG(LS_INFO) << "MMF: Device added: " << deviceId;

addDevice(deviceId);
// IMMNotificationClient callbacks run on a system thread. An exception that leaves one
// has no handler above it and terminates the process, so it is logged and dropped.
try {
addDevice(deviceId);
}
catch (const std::exception & e) {
RTC_LOG(LS_ERROR) << "MMF: Device added handling failed: " << e.what();
}
catch (...) {
RTC_LOG(LS_ERROR) << "MMF: Device added handling failed";
}

return S_OK;
}
Expand All @@ -417,7 +428,15 @@ namespace jni
{
RTC_LOG(LS_INFO) << "MMF: Device removed: " << deviceId;

removeDevice(deviceId);
try {
removeDevice(deviceId);
}
catch (const std::exception & e) {
RTC_LOG(LS_ERROR) << "MMF: Device removed handling failed: " << e.what();
}
catch (...) {
RTC_LOG(LS_ERROR) << "MMF: Device removed handling failed";
}

return S_OK;
}
Expand All @@ -430,16 +449,24 @@ namespace jni
return S_OK;
}

switch (newState) {
case DEVICE_STATE_ACTIVE:
addDevice(deviceId);
break;

case DEVICE_STATE_DISABLED:
case DEVICE_STATE_NOTPRESENT:
case DEVICE_STATE_UNPLUGGED:
removeDevice(deviceId);
break;
try {
switch (newState) {
case DEVICE_STATE_ACTIVE:
addDevice(deviceId);
break;

case DEVICE_STATE_DISABLED:
case DEVICE_STATE_NOTPRESENT:
case DEVICE_STATE_UNPLUGGED:
removeDevice(deviceId);
break;
}
}
catch (const std::exception & e) {
RTC_LOG(LS_ERROR) << "MMF: Device state change handling failed: " << e.what();
}
catch (...) {
RTC_LOG(LS_ERROR) << "MMF: Device state change handling failed";
}

return S_OK;
Expand Down