我正在开发一款需要独家访问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);
}
}