Я занимаюсь разработкой приложения, которое должно иметь эксклюзивный доступ к звуковому устройству USB. Я обнаружил, что когда музыка воспроизводится с помощью этого устройства, то иногда невозможно получить доступ. Поэтому мне нужно остановить и перезапустить демон CoreAudio.
Я использую этот кусок кода (ниже), чтобы заставить его работать. Но проблема в том, что после остановки coreaudiod я могу запустить его только под пользователем root. По умолчанию он запускается под _coreaudiod
пользователь. Как я могу запустить его под _coreaudiod
пользователь как это делает ОС?
#include <CoreFoundation/CFDictionary.h>
#include <Security/Authorization.h>
class ScopedAudioServiceStopper
{
public:
ScopedAudioServiceStopper();
~ScopedAudioServiceStopper();
void stop();
private:
void start();
private:
AuthorizationRef m_authorizationRef;
CFDictionaryRef m_coreAudiodDictionary;
};
ScopedAudioServiceStopper::~ScopedAudioServiceStopper()
{
start();
if (m_coreAudiodDictionary)
CFRelease(m_coreAudiodDictionary);
if (m_authorizationRef)
AuthorizationFree(m_authorizationRef, kAuthorizationFlagDestroyRights);
}
void ScopedAudioServiceStopper::stop()
{
m_coreAudiodDictionary = SMJobCopyDictionary(kSMDomainSystemLaunchd, CFSTR("com.apple.audio.coreaudiod"));
if (!m_coreAudiodDictionary) //means daemon is not started
return;
if (errAuthorizationSuccess != AuthorizationCreate(nullptr, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &m_authorizationRef)) {
m_authorizationRef = nullptr;
return;
}
AuthorizationItem authItem = { kSMRightModifySystemDaemons, 0, nullptr, 0 };
AuthorizationRights authRights = { 1, &authItem };
AuthorizationFlags flags = kAuthorizationFlagDefaults |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagExtendRights;
// Obtain the right to install our privileged helper tool (kSMRightModifySystemDaemons).
if (errAuthorizationSuccess != AuthorizationCopyRights(m_authorizationRef, &authRights, kAuthorizationEmptyEnvironment, flags, nullptr)) {
m_authorizationRef = nullptr;
return;
}
CFErrorRef cfError;
if (!SMJobRemove(kSMDomainSystemLaunchd, CFSTR("com.apple.audio.coreaudiod"), m_authorizationRef, TRUE, &cfError)) {
CFRelease(cfError);
}
}
void ScopedAudioServiceStopper::start()
{
if (!m_authorizationRef || !m_coreAudiodDictionary)
return;
CFErrorRef cfError;
if (!SMJobSubmit(kSMDomainSystemLaunchd, m_coreAudiodDictionary, m_authorizationRef, &cfError)) {
CFRelease(cfError);
}
}
Задача ещё не решена.
Других решений пока нет …